<School>
<Child_One>
<Subject>
<name>computers</name>
<marks>55</marks>
<name>mathematics</name>
<marks>44</marks>
</Subject>
<Child_One>
<Child_Two>
<name>computers</name>
<marks>66</marks>
<name>mathematics</name>
<marks>77</marks>
</Child_Two>
</School>
Can anybody help me to find the Child_One subject name, in which he got highest marks
Thanks
First of all a few formatting things:
Your XML is not quite well formatted. It should have the same start and end tags
I believe the Subject element should look different then posted
When posting a input XML, don't use backticks, but indent the XML with 4 spaces to format it well on Stackoverflow
I used and changed the input XML to this:
<?xml version="1.0" encoding="UTF-8"?>
<School>
<Child_One>
<Subject>
<name>computers</name>
<marks>55</marks>
</Subject>
<Subject>
<name>mathematics</name>
<marks>44</marks>
</Subject>
</Child_One>
<Child_Two>
<Subject>
<name>computers</name>
<marks>66</marks>
</Subject>
<Subject>
<name>mathematics</name>
<marks>77</marks>
</Subject>
</Child_Two>
</School>
With XPath 2.0 you can use the following the find the max value:
/School/Child_One/Subject[marks = max(/School/Child_One/Subject/marks)]/name
With XPath 1.0 you can use the following (replace < with > to find minimum):
/School/Child_One/Subject[not(marks < /School/Child_One/Subject/marks)][1]/name
Related
I am learning for an exam and i can't quite figure out what i am doing wrong here.
i got this xml
<?xml version="1.0"?>
<schema xmlns=""
xmlns:xsi="link-2"
xsi:schemeLocation="link-3">
<wm-stats>
<wm jahr="2014">
<teilnehmer platz="1">Deutschland</teilnehmer>
<teilnehmer platz="2">Argentinien</teilnehmer>
<teilnehmer platz="3">Niederlande</teilnehmer>
</wm>
<wm jahr="2010">
<teilnehmer platz="1">Spanien</teilnehmer>
<teilnehmer platz="2">Holland</teilnehmer>
<teilnehmer platz="3">Deutschland</teilnehmer>
</wm>
<wm jahr="2006">
<teilnehmer platz="1">Italien</teilnehmer>
<teilnehmer platz="2">Frankreich</teilnehmer>
<teilnehmer platz="3">Deutschland</teilnehmer>
</wm>
<record name="Rekordtorschütze">
<person> Miroslav Klose </person> hat in Brasilien ...
</record>
<record name="Rekordweltmeisterschaften">
<ort> Brasilien </ort> ist mit 5 Weltmeistersiegen ...
</record>
</wm-stats>
</schema>
i now need to find all the years where holland was taking part in the championship, i know that i have to look for something like this //wm[#jahr]/teilnehmer[text()="Holland"]
But how do i get the value of jahr now? the correct node to be located would be jahr 2010.
The other way around
//wm[teilnehmer = "Holland"]/#jahr
but your approach is not unsalvageable, either
//wm[#jahr]/teilnehmer[. ="Holland"]/../#jahr
* note that [#jahr] is actually superfluous in this expression
You can always navigate upwards (and sideways) in XPath.
Have a look at this comprehensive image explaining the various XPath axes available for navigation: https://our.umbraco.org/wiki/reference/xslt/xpath-axes-and-their-shortcuts/
I have been using the following xpath selection in xpath 1.0
<xsl:variable name="id"><xsl:value-of select="./#id" /></xsl:variable>
preceding::exm:messageFlow[#sourceRef = $id]/#targetRef
This worked very well and did exactly what I wanted.
However I started using XSLT 2.0 in combination with xPath 2.0 and this does not work anymore
(Using the Altova XML processor)
I get the following error:
Kann nicht mit Ziel-Typ besetzt werden - Aktuelles Element ist 'sid-B3FD7EE5-043
3-4939-A69F-E74B30FDEB1C' vom Typ xs:untypedAtomic, Typ xs:QName erwartet - =
which translates roughly to:
Cannot be set to target-type - Current element is 'sid-B3FD7EE5-043
3-4939-A69F-E74B30FDEB1C' of type xs:untypedAtomic, type xs:QName
expected -
Previously I had a similar problem with this selection:
following::exm:*[exm:incoming = $out] | preceding::exm:*[exm:incoming = $out]
Which again worked in xpath 1.0, but returned a similar error in xPath 2.0
After changing it to
following::exm:*[exm:incoming/text() = $out] | preceding::exm:*[exm:incoming/text() = $out]
It worked in xPath 2.0 as well. I did try doing something similar with the attributes, but it did not work
A small extract of the corresponding XML:
<messageFlow id="sid-80B618A4-E6BF-4438-AF5D-5111AD308FE6" name="" sourceRef="sid-B3FD7EE5-0433-4939-A69F-E74B30FDEB1C" targetRef="sid-6EB2DB76-CC19-48AD-A073-D37C7489F211"/>
<task completionQuantity="1" id="sid-B3FD7EE5-0433-4939-A69F-E74B30FDEB1C" isForCompensation="false" name="call service" startQuantity="1">
<incoming>sid-2B2BA651-B5BA-4195-9B5B-E6855B1138F4</incoming>
<incoming>sid-DA4B86E8-C3F2-497C-8C0D-218E95CE9FD1</incoming>
<outgoing>sid-008948DE-BA59-4897-AC37-2C3AA63DCD82</outgoing>
</task>
I wonder if you have a schema that declares the #id attribute as being of type QName?
With this variable declaration:
<xsl:variable name="id"><xsl:value-of select="./#id" /></xsl:variable>
you are creating a copy of the #id attribute in a new result tree fragment. This is quite unnecessary; your needs would almost certainly be better served by making the variable be simply a reference to the existing attribute, thus:
<xsl:variable name="id" select="#id" />
By making the copy, you are not only writing unnecessary code and incurring unnecessary run-time cost (building a new tree is an expensive operation), but you are also losing the type information. If my conjecture is correct that #id is of type xs:QName, then the variable $id after atomization will be of type xs:untypedAtomic, and comparing it to an xs:QName is likely to fail with a message similar to the one cited.
I can't reproduce the problem.
This transformation:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="task">
<xsl:variable name="id"><xsl:value-of select="./#id" /></xsl:variable>
<xsl:variable name="vResult"
select="preceding::messageFlow[#sourceRef = $id]/#targetRef"/>
<xsl:value-of select="$vResult"/>
</xsl:template>
</xsl:stylesheet>
when applied on the following document (the provided fragment wrapped in a single top element and stripped off any undefined namespaces):
<t>
<messageFlow id="sid-80B618A4-E6BF-4438-AF5D-5111AD308FE6"
name="" sourceRef="sid-B3FD7EE5-0433-4939-A69F-E74B30FDEB1C"
targetRef="sid-6EB2DB76-CC19-48AD-A073-D37C7489F211"/>
<task completionQuantity="1" id="sid-B3FD7EE5-0433-4939-A69F-E74B30FDEB1C"
isForCompensation="false" name="call service" startQuantity="1">
<incoming>sid-2B2BA651-B5BA-4195-9B5B-E6855B1138F4</incoming>
<incoming>sid-DA4B86E8-C3F2-497C-8C0D-218E95CE9FD1</incoming>
<outgoing>sid-008948DE-BA59-4897-AC37-2C3AA63DCD82</outgoing>
</task>
</t>
when run with both Altova2011 and Saxon 9.1.07, produces the expected, correct result and no error is raised:
sid-6EB2DB76-CC19-48AD-A073-D37C7489F211
I am trying to parse XML files using Nokogiri, Ruby and XPath. I usually don't encounter any problem but with the following I can't make any xpath request:
doc = Nokogiri::HTML(open("myfile.xml"))
doc.("//Meta").count
# result ==> 0
doc.xpath("//Meta")
# result ==> []
doc.xpath(.).count
# result => 1
Here is an simplified version of my XML File
<Answer xmlns="test:com.test.search" context="hf%3D10%26target%3Dst0" last="0" estimated="false" nmatches="1" nslices="0" nhits="1" start="0">
<time>
...
</time>
<promoted>
...
</promoted>
<hits>
<Hit url="http://www.test.com/" source="test" collapsed="false" preferred="false" score="1254772" sort="0" mask="272" contentFp="4294967295" did="1287" slice="1">
<groups>
...
</groups>
<metas>
<Meta name="enligne">
<MetaString name="value">
</MetaString>
</Meta>
<Meta name="language">
<MetaString name="value">
fr
</MetaString>
</Meta>
<Meta name="text">
<MetaText name="value">
<TextSeg highlighted="false" highlightClass="0">
La
</TextSeg>
</MetaText>
</Meta>
</metas>
</Hit>
</hits>
<keywords>
...
</keywords>
<groups>
...
</groups>
How can I get all children of <Hit> from this XML?
Include the namespace information when calling xpath:
doc.xpath("//x:Meta", "x" => "test:com.test.search")
You can use the remove_namespaces! method and save your day.
This is one of the most FAQ XPAth questions -- search for "XPath default namespace".
If there is no way to register a namespace for the default namespace and use the registered prefix (say "x" in //x:Meta) then use:
//*[name() = 'Meta` and namespace-uri()='test:com.test.search']
If it is known that Meta can only belong to the default namespace, then the above can be shortened to:
//*[name() = 'Meta`]
I'm pulling the following XML from mediawiki API
<?xml version="1.0"?>
<api>
<query>
<pages>
<page pageid="309311" ns="0" title="Chenonetta jubata">
<images>
<im ns="6" title="File:Australian Wood Duck.jpg" />
<im ns="6" title="File:Australian Wood Duck Female.JPG" />
<im ns="6" title="File:Australian Wood Duck Male.JPG" />
...
</images>
</page>
</pages>
</query>
</api>
and reading it into a Ruby map using xmlSimple. The data which I'm really trying to get is the image names from the images section but when I attempt to go past the query level with
x= result['query']['pages']
puts x
I'm getting the following error:
in `[]': can't convert String into Integer (TypeError)
what am I doing wrong?
Thanks,
m
I used Nokogiri in the end which allows xpath notation to traverse the xml tree.
e.g.
licenseinfo = results3.xpath("//api/query/pages/page/categories/cl/#title")
My XML:
<root>
<cars>
<makes>
<honda year="1995">
<model />
<!-- ... -->
</honda>
<honda year="2000">
<!-- ... -->
</honda>
</makes>
</cars>
</root>
I need a XPath that will get me all models for <honda> with year 1995.
so:
/root/cars/makes/honda
But how to reference an attribute?
"I need a XPath that will get me all models for <honda> with year 1995."
That would be:
/root/cars/makes/honda[#year = '1995']/model
Try /root/cars/makes/honda/#year
UPDATE: reading your question again:
/root/cars/makes/honda[#year = '1995']
Bottom line is: use # character to reference xml attributes.