Reputation: 524
Let's say we have the following XML:
<people>
<student name="Peter">
<subject>
<name>English</name>
<grade>60</grade>
</subject>
<subject>
<name>Programming</name>
<grade>70</grade>
</subject>
<diploma>80</diploma>
</student>
</people>
What we're trying to find is the "name" of the "subject" where "Peter" has the largest number in "Grade". The entire XML has a few more people with different names but I dont think that matters. It all follows the same principle.
How come this XPath fails:
people/student[@name="Peter"][max(subject/grade)]/subject/name
The error is called:
NO MATCH!
I've never been able to use the max function correctly if I had to print out a different value after calculating the maximum value.
I've also spent quite a few minutes on XMLLINT trying to make it work in Xpath1.0
xmllint --xpath 'people/student[name='Peter'][not(subject/grade > subject/grade)]/subject/grade' grades.xml >result.txt
This returns:
XPath set is empty
I've read up on the functions, so I would appreciate code examples and not links to documentations. If you find an XML error there's probably been an issue when I was manually translating this into english.
EDIT:
people/student[@name="Peter"]/max(subject/grade)
Worked fine and outputted the correct maximum value. Which leads me to believe the problem is with my usage of [] .
Upvotes: 1
Views: 1491
Reputation: 52858
Your use of max()
didn't work because you aren't comparing max() to anything.
Here are a couple of options...
XPath 2.0
/people/student[@name="Peter"]/subject[grade = max(../subject/grade)]/name
XPath 1.0
/people/student[@name="Peter"]/subject[not(preceding-sibling::subject/grade > grade) and not(following-sibling::subject/grade > grade)]/name
Note that xmllint only supports XPath 1.0.
Upvotes: 1
Reputation: 1133
I have tried this one with this parser and it returns "Programming". Not sure if it will work with the one you are using:
people/student[@name="Peter"]/subject[number(grade) = max(/people/student[@name="Peter"]/subject/number(grade))]/name
Upvotes: 0