XPath 1.0 attribute axes: no chance? - xpath

Beginner's question here:
Given the following XML excerpt:
<root>
<element>
<child1>a</child1><child2>b</child2><child3>c</child3>
</element>
</root>
When I'm at the child3 context, I can use preceding-sibling::* to get the child2 node. All right.
In the following XML excerpt:
<root>
<element child1="a" child2="b" child3="c">
</element>
</root>
When I'm at the child3 context, is it right that there is no axis in XPath 1.0 to get the child2 attribute node? I think I'd need something like preceding-sibling-attribute:: that is not available.
As a side question, is this possible with XPath 2?

It's true that there is no single axis to get from one attribute to another, but of course you can get there by chaining axes.
Attributes are not considered siblings, because they are not considered 'children' of the parent element, in the data model XPath uses. That's one reason why preceding-sibling:: won't work. It also means that attribute names such as child1, child2 etc. are misleading in that attributes are not "children".
The other reason preceding-sibling:: won't work is that the order of attributes of a given element is undefined (implementation-dependent). Attributes must be listed in some order in a given serialization (e.g. in a file), but that file could be parsed and output again with the attributes in a different order, and it would still be considered the same document from an XML info model point of view. Therefore, there is no such thing as the "previous" or "preceding" attribute in XML.
To get the value of the child2 attribute from the context of the child3 attribute, you can use one of these depending on how you know which attribute you want...
../#child2
"The attribute named child2 of the parent element"
../#*[name() != name(current())]
"The other attributes of the parent element (not this one)"
You could even try
../#*[2]
but the results would not be predictable in general, since the order of attributes is undefined.
If the attribute names include an index component (1, 2, 3) as in your example, you could replace the number in name(current()) with a smaller number.
To answer your side question, it depends on how your requirement is defined. If the requirement is "select the previous attribute", then no, that concept is not defined in XPath 2 either.

Related

Appending type data inline

In my use case I have a RAML 1.0 library created by our R&D department that contains definition of multiple data types. Those data types are defined in a generic, parametrized manner so when I reference them in my RAML I do so using following syntax:
type: { resourceTypes.collectionWithCriteria: {itemName: reward, itemCriteria: types.RewardCriteria, itemType : types.RewardList} }
This generates proper GET request with query string defined by types.RewardCriteria and response defined by types.RewardList. It also generates the description for the GET resource defined as: Retrieves the list of <<itemName | !pluralize>>, which ends up being Retrieves the list of rewards.
In my RAML I would like to append additional description to my GET resource, however I 'd rather avoid overwriting library-generated one. Is that possible? I've already tried inline description and using overlay file, both of which simply replace description from the library.
You cannot append for a single value simple property.
The merging rules for traits / resource types state that the description will be replaced:
Every explicit node wins over the ones that are declared in a resource
type or trait. The rest are simply merged.
Also, the merging rules of overlays and extensions states that:.
If the property is a Simple Property
If the property is a Single-value Simple Property,
The property value in the identically named Current Target Tree Object property is replaced with its value from Current Extension Tree Object property.

Can Freemarker macro parameters use other parameters for their default values?

We have a number of Freemarker macros to simplify HTML pages, eg <#macro.textfield id name label .../> can automatically add a label tag, standard CSS classes, etc. To cover all our use cases, there are a number of parameters with default values.
However, we would ideally like more advanced defaults than simple literals. For example, if a text field doesn't have a custom value specified, then it should default to getting it from the model using the name parameter, eg ${parameters[name]!}. The name, in turn, can usually be derived from the ID; a field with id="foo" will most likely need name="form.foo". Is there an efficient way to do this?
The default value is just a usual expression, thus it can refer to a data model variable (among others) like this: <#macro something name=form.name>. It can also refer to another macro parameter: <#macro something p1 p2=p1>. (Order doesn't mater, FreeMarker will figure out the correct evaluation order. Even cyclic dependencies like p1=p2 p2=p1 are allowed, as it can be resolved when you specify at least one of the parameters in the call.)
See also: https://freemarker.apache.org/docs/ref_directive_macro.html#ref.directive.macro

Copy a Nokogiri node to a custom subclass

I have an XML document that I'm parsing using ::parse, and there are few descendant elements inside the root node of the document that I would like to create copies of, but as a custom subclass of Nokogiri::XML::Element.
It seems like
MyElement.new('myElement', existingElement)
should do it, but the new object ends up being empty, except for the name. I'm hoping there's a better way of doing it than just iterating over all the attributes, and manually assigning the children, namespace, etc to the new object.
Is there something like a class method for #dup that takes an existing element? Or some other way of handling this?

eclipselink moxy xpath - selecting all child elements of the current node or all elements in a document with a particular name

i have this xpath defined for moxy in a jaxb class
#XmlPath("child::*/REG")
public List entries;
but it won't unmarshal the xml document correctly. the List variable called entries is empty.
i've also tried
#XmlPath("*/REG")
public List entries;
i've also tried
#XmlPath("//REG")
public List entries;
without joy
but if i do
#XmlPath("BANKGIRO/REG")
public List entries;
it's fine and the list is populated.
I haven't looked through the source yet but I'm guessing this type of xpath is not supported yet. I checked all my xpath in an xpath verifier for sanity and all the xpath above is fine (all the xpath is valid for the context node i'm positioned at).
EclipseLink JAXB (MOXy) does currently not support an XPath like: #XmlPath("child::*/REG"). Our focus has been on supporting XPath statements that provide enough information for marshalling as well as unmarshalling. For example it is clear what #XmlPath("child::*/REG") means on a read, but is ambiguous in terms when writing that object back to XML or JSON. If you are interested in this kind of support please enter an enhancement request:
https://bugs.eclipse.org/bugs/enter_bug.cgi?product=EclipseLink
MOXy does support XPath like:
#XmlPath(".") // Map to self node, useful when mapping two objects to same element
#XmlPath("#foo") // Map to attribute
#XmlPath("foo") // Map to element
#XmlPath("foo[2]") // Map to 2nd occurence of
#XmlPath("foo[#bar='Hello World']") // Map to foo element with bar attribute with value "Hello World"
#XmlPath("ns1:foo/ns2:#bar") // Map to namespace qualified nodes
For More Information
http://blog.bdoughan.com/2010/07/xpath-based-mapping.html
http://blog.bdoughan.com/2010/09/xpath-based-mapping-geocode-example.html
http://blog.bdoughan.com/2011/03/map-to-element-based-on-attribute-value.html

What Query/Path-Language is used for References in Ecore-derived XMI-Instances?

Assume that I have an Ecore-model containing a package and some classes that make reference to each other. If i create a "Dynamic Instance", Eclipse produces an XMI-file and I can instantiate some classes. Containment-relations are directly serialized to an XML-tree in the XMI (the children elements in the example). But if I instantiate references to elements that are already contained somewhere in the tree, the Editor writes Path-Expressions like in the following, for the currentChild attribute:
<parent currentChild="//#parent/#children.1">
<children/>
<children/>
</parent>
As far as I know this is not XPath, because:
The "childrens" are elements not attributes and have not to be referenced via "#"
XPath uses the e.g., elem[1] and not elem.1 to get e.g., the second elem of a list
What is it and where can I find a information on it? I already tried to browse the EMF pages/specs but could not find it.
It's an EMF Fragment Path. The Javadoc describes it like this:
String org.eclipse.emf.ecore.InternalEObject.eURIFragmentSegment(EStructuralFeature eFeature, EObject eObject)
Returns the fragment segment that, when passed to eObjectForURIFragmentSegment, will resolve to the given object in this object's given feature.
The feature argument may be null in which case it will be deduced, if possible. The default result will be of the form:
"#feature-name[.index]"
The index is used only for many-valued features; it represents the position within the list.
Parameters:
eFeature the feature relating the given object to this object, or null.
eObject the object to be identified.
Returns:
the fragment segment that resolves to the given object in this object's given feature.

Resources