Syntax of the xml document:
<x name="GET-THIS">
<y>
<z>Z</z>
<z>Z__2</z>
<z>Z__3</z>
</y>
</x>
I'm able to get all z elements using:
xpath("//z")
But after that I got stuck, I'm not sure what to do next. I don't really understand the syntax of the .. parent method
So, how do I get the attribute of the parent of the parent of the element?
Instead of traversing back to the parent, just find the right parent to begin with:
//x will select all x elements.
//x[//z] will select all x elements which have z elements as descendants.
//x[//z]/#name will get the name attribute of each of those elements.
You already have a good accepted answer, but here are some other helpful expressions:
//z/ancestor::x/#name - Find <z> elements anywhere, then find all the ancestor <x> elements, and then the name="…" attributes of them.
//z/../../#name - Find the <z> elements, and then find the parent node(s) of those, and then the parent node(s) of those, and then the name attribute(s) of the final set.
This is the same as: //z/parent::*/parent::*/#name, where the * means "an element with any name".
The // is useful, but inefficient. If you know that the hierarchy is x/y/z, then it is more efficient to do something like //x[y/z]/#name
I dont have a reputation, so I cannot add comment to accepted answer by Blender. But his answer will not work in general.
Correct version is
//x[.//z]/#name
Explanation is simple - when you use filter like [//z] it will search for 'z' in global context, i.e. it returns true if xml contains at least one node z anywhere in xml. For example, it will select both names from xml below:
<root>
<x name="NOT-THIS">
</x>
<x name="GET-THIS">
<y>
<z>Z</z>
<z>Z__2</z>
<z>Z__3</z>
</y>
</x>
</root>
Filter [.//z] use context of current node (.) which is xand return only 2nd name.
Related
Integer fun(Node *p) //Linked list
while(p not equals NULL)
print p-> data
p=p->next
End loop
Well, that's a common linked list function. Here is a common linked list architecture:
The idea is that you have blocks with two contents: the actual data and the pointer to the next object of the list.
In the posted code, p is the pointer to the first element of the list.
The intention is to print all the list. So, it follows the steps:
Print the first element's data.
Update p to point to the next element.
Print this element's data.
and so on until there are no more elements.
I have code which retrieves a static text element for me fine but what I want to do is then get the xpath of that element as a string. I'm using ruby. At this point I have an array of elements I have already retrieved. Below is what I've tried but no luck.
elements.each do |element|
if element.attribute("name").include? vProblem
p "Problem found, retrieving xpath..."
# Neither of these work
p "Problem xpath is: " + element.attribute("xpath").to_s
p "Problem xpath is: " + element.xpath.to_s
end
end
I don't believe there's an easy method or setting to call which will give you the xpath value. You would have to determine it yourself. To do this, iterate through all elements on the page until you found one that (A) matched the class of the element you're looking for and (B) matches the name/value of the element.
The only issue with this approach is that it assumes that the first element matching the class and value is the correct element. If there are multiple elements with the same class and value, it will only find the first.
I want to redefine the order of a tuple looking for specific words
Example, I have a list of tuples like this:
[{"a",["r001"]},
{"bi",["bidder"]},
{"bo",["an"]}]
But sometimes the order of the tuples can change for example:
[{"bi",["bidder"]},
{"a",["r001"]},
{"bo",["an"]}]
or
[{"bo",["an"]},
{"a",["r001"]},
{"bi",["bidder"]}]
The first string/list of the tuple is my unique key ("bo","a","bi")
But I want to be able to reorder the list of tuples, always like:
[{"a",["r001"]},
{"bi",["bidder"]},
{"bo",["an"]}]
How can I achieve this?
This will do it:
lists:sort(fun({A,_},{B,_}) -> A =< B end, List).
Or this, which will sort by the tuples second element after the first:
lists:sort(List).
I offer the second version, because without the custom sort function, it is faster for data like this.
If you need to sort by specified element, you just sort by specified element
lists:keysort(1, List).
<xsl:template match="lat:entry[document(lat:file)//h2]"/>
Is this template called ONLY on "entry" elements that contain a lat:file tag with a file name, which file contains h2 tags?
Or on ANY lat:entry ?
If the latter, how can I construct a correct match? (correct being the former option)
That match pattern lat:entry[document(lat:file)//h2] indeed matches elements with local name entry with the namespace matched by the prefix lat which have one or more file child element in the same namespace where document(lat:file) finds at least one XML document containing h2 elements (in no namespace or in the xpath-default-namespace, depending on the context). So your first description is kind of right, with the exception that document(lat:file)//h2 could result in several documents being loaded and checked for h2 elements, if there are several lat:file child elements.
Is it possible to find the difference two nodes and use the that difference as a constraint for a particular control.
<xforms:bind id="DebitRebate1"
nodeset="instance('charge-options-setup')/Pattern_Setup1/Pattern1/DebitRebate1"
type="xforms:double"
constraint=". < instance('charge-options-setup')/Pattern_Setup1/Pattern1/DebitPrice1
and instance('charge-options-setup')/Pattern_Setup1/Pattern1/DebitPrice1-. >
instance('charge-options-setup')/Locations_Patterns/Debit_Minimum_Margin"/>
Yes, you can use the difference between two nodes as a constraint on another node, and the code you quote seems about right. Just a couple of comments:
In your XPath, instead of < and > you can use just lt and gt. This performs a value comparison, and makes the expression easier to read.
Also make sure you have spaces around node named: instead of DebitPrice1-. use DebitPrice1 - .. This is necessary, as - can be used as part of an element or attribute name, so foo-bar point to <foo-bar> not what's in <foo> minus what's in <bar>.