I'm adding Apple Event scripting to my application. I would like to be able to use both of the statements below on it:
-- Every instance of MyObject in the app
every MyObject
-- Only the instances of MyObject the user has selected
selected MyObjects
These are relevant excerpts from of my sdef file:
<dictionary>
<suite ...>
<class name="application" code="capp" description="Top-level scripting object" plural="applications" inherits="application">
<cocoa class="MyAppClass" />
<element type="MyObject" access="r">
<cocoa key="myobjects" />
</element>
<element name="selected MyObjects" code="ABCD" type="MyObject" access="rw">
<cocoa key="selectedMyObjects" />
</element>
</class>
<class name="MyObject" code="ABcd" inherits="item" plural="MyObjects">
...
</class>
</suite>
</dictionary>
When I call every MyObject, it returns a list of objects, as expected. But when I call selected MyObjects, the Script Editor selects the "MyObjects" portion and complains:
Syntax Error
Expected end of line, etc. but found plural class name.
How can I achieve what I'm looking to do?
Your design is wrong. See the Scripting Interface Guidelines for a somewhat thin but better-than-nothing outline of good UX practices.
The correct idiom is to define a selection property, typically on application and/or document. This may be read-write or read-only, depending on what's appropriate to your application.
The selection property's value is either:
A single bespoke object specifier that identifies all of the currently selected objects e.g.:
selection of application "Foo"
or
selection of document X of application "Foo"
Some of the better Carbon-based apps and the occasional Cocoa app use this approach, which allows users to perform powerful queries such as:
get (name of every MyObject of selection of document X)
delete (every job whose status is completed)
but requires more work for you to implement.
A list of single-object specifiers, each identifying one selected item, e.g.:
{thing B of document X of application "Foo",
thing E of document X of application "Foo",...}
This is less powerful, since users cannot manipulate all of the selected items in a single command but must instead iterate the list processing each item one at a time, but is cheaper for you to implement. Cocoa Scripting being somewhat lame and inflexible even at the best of times, and pretty damn hopeless at moving/duplicating/deleting more than one object at a time, this is the most common approach in Cocoa-based apps.
Update your sdef file with this property:
<property name="selection" code="ABCD">
<cocoa key="selectedMyObjects" />
<type type="MyObject" list="yes" />
</property>
For an example of the first (better) design approach, take a look at Script Editor's own dictionary. For an example of the second, see Mail's dictionary.
(Tip: To view a dictionary in Script Editor, choose File>Open Dictionary and select the appropriate item from the list. To export that dictionary as an SDEF file, just make sure the dictionary viewer window is frontmost and choose File>Save As.)
Related
Using XSD schema validation 1.0 I want to verify an element has at least one attribute specified.
For example, a simple element like this:
<foo a="1" b="2" c="3" />
I want to verify that at least attribute b or c is specified. But note that both can also be specified--they're not mutually exclusive.
I tried using a key along the lines of:
<xs:key name="AttributeSpecified">
<xs:selector xpath="." />
<xs:field xpath="#b|#c" />
</xs:key>
but it fails when both attributes are specified (because multiple results are returned).
Can it be done?
This is not possible in XSD 1.0. It might be possible in XSD 1.1.
I am a fan of XML Schema, but I would not choose it for this type of validation. You might be able to make it work using XSD1.1 but if your requirements became just a little more complex you could end up with some horrible-looking constraints.
On the other hand, an XPath expression can elegantly express any constraint you can think of, and you would not need to bend the language to make it work.
I was selecting all attributes id and everything was going nicely then one day requirements changed and now I have to select all except one!
Given the following example:
<root>
<structs id="123">
<struct>
<comp>
<data id="asd"/>
</comp>
</struct>
</structs>
</root>
I want to select all attributes id except the one at /root/structs/struct/comp/data
Please note that the Xml could be different.
Meaning, what I really want is: given any Xml tree, I want to select all attributes id except the one on element /root/structs/struct/comp/data
I tried the following:
//#id[not(ancestor::struct)] It kinda worked but I want to provide a full xpath to the ancestor axis which I couldn't
//#id[not(contains(name(), 'data'))] It didn't work because name selector returns the name of the underlying node which is the attribute not its parent element
The following should achieve what you're describing:
//#id[not(parent::data/parent::comp/parent::struct/parent::structs/parent::root)]
As you can see, it simply checks from bottom to top whether the id attribute's parent matches the path root/structs/struct/comp/data.
I think this should be sufficient for your needs, but it does not 100% ensure that the parent is at the path /root/structs/struct/comp/data because it could be, for example, at the path /someOtherHigherRoot/root/structs/struct/comp/data. I'm guessing that's not a possible scenario in your XML structure, but if you had to check for that, you could do this:
//#id[not(parent::data/parent::comp/parent::struct/parent::structs/parent::root[not(parent::*)])]
I'm trying to figure out how to fully specify a sliced element. If I'm reading the spec right, nameReference is the only place where a "sub element" of a slice can declare which slice it's "on".
So, if telecom is sliced by use and system and I want to specify a constraint on home phone, I have to fix use and system to those values and then add my constraints on that slice.
Consider:
Resource Example ElementDefinition attributes
================================ =====================================================================
<Patient> name="Patient"
... snip ...
<telecom> name="HomePhone"
<system value="phone" /> name="HomePhone.system", nameReference="HomePhone", fixedCode="phone"
<use value="home" /> name="HomePhone.use" , nameReference="HomePhone", fixedCode="home"
<value value="5551234567" /> name="HomePhone.value" , nameReference="HomePhone"
</telecom>
... snip ...
</Patient>
In most examples, it appears that a dotted notation of Name has been used (as I've placed in the example). But the specification doesn't require this and provides no format that could be reliably parsed.
The problem is: nameReference and fixed[x] are mutually exclusive. What's the correct way to handle this??
Repetitions in an instance don't "declare" what slice they're part of. They simply declare the appropriate value for what ever element(s) are the discriminator for the slicing process. nameReference isn't involved at all. On the definition side, association is simply handled by name. So HomePhone.system is associated with HomePhone simply by the name and by sequential proximity. The dot-notation is required. We could probably be a bit more explicit about that though, so feel free to submit a change request.
I have an xml document that I would like to parse using freemarker. The XML document itself was auto generated using SAX in my smooks script. This smooks script created the following XML with element names derived from the actual java package names that I have in my workspace.
<map>
<entry>
<string>RunReportMsg</string>
<com.web.ws.messages.v1__2.RunReportMsg>
<analyticsReport>
<columns>
<com.web.ws.objects.v1__2.ReportColumn>
<dataType>
<id>
<id>10</id>
</id>
</dataType>
</com.web.ws.objects.v1__2.ReportColumn>
</columns>
<analyticsReport>
</com.web.ws.messages.v1__2.RunReportMsg>
</entry>
</map>
A similar question has been posted on this site about this. But I cannot figure out how this would solve my problem.
Access XML elements with names containing a period/dot in FreeMarker templates
I know how to access "RunReportMsg" text in the element "string".
${map.entry.string}
How do I access data in the following child element using dotted notation in freemarker? As the element "com.web.ws.messages.v1__2.RunReportMsg" has multiple periods, I am not sure how to traverse down through further child elements. I need a way to find out the number in the following "id" element.
<id>10</id>
I read the documentation on expressions in freemarker site on ".vars". I am not sure if this applies to my case.
Any help is deeply appreciated.
You can use this syntax:
${map.entry["com.web.ws.messages.v1__2.RunReportMsg"].analyticsReport.columns["com.web.ws.objects.v1__2.ReportColumn"].dataType.id.id}
I can't navigate the XML doc programmatically and I need an one-line XPath solution for reasons I describe at the end.
I am working with an XML schema that looks something like the one below. (This is something I have to use as-is.)
<Root>
<!-- Child 1 -->
<Child>
<Name>Joe</Name>
<Age>12</Age>
</Child>
<!-- Child 2 -->
<Child>
<Name>Mike</Name>
<Age>25</Age>
</Child>
<!-- Child 3 -->
<Child>
<Name>Jane</Name>
<Age>20</Age>
</Child>
</Root>
Assuming I'm already at the "Joe" node (i.e. the Name element inside Child 1), I need to define an XPath query that will "wrap" that node as follows:
<Root>
<!-- Child 1 -->
<Child>
<Name>Joe</Name>
<Age>12</Age>
</Child>
</Root>
I've tried various combinations of ancestor, string-join, concat, etc., but can't seem to find the solution that "wraps" the element correctly. (The way I was using ancestor was returning all Child nodes, for example, which is not what I need.)
Some other considerations:
The solution has to be a one-line XPath query, if that's possible (for reasons given below).
It has to be generic enough to work for any Child element (i.e., it can't assume that I'm always at the first or second or third child, for example).
From the example above, you can see that I don't actually need the actual Root node per-se, just its tag (i.e. I don't want all Child nodes under it). However, I do need the actual Child node (so that I get the Name and Age).
NOTE: For what it's worth, I can't actually navigate the XML programmatically. I am using a library (whose code I cannot change) in which I have to define everything in terms of one-line XPath queries within a configuration file. It will essentially navigate through all of the Name elements, so my solution has to work from that point.
XPath is a query language.
This, among other things means that the evaluation of an XPath expression never modifies the XML document.
So, the answer is: Modifying an XML document or creating a new document cannot be done using only XPath.
Such transformations are very easy and natural to specify with XSLT.