StefH / XPath2.Net

Lightweight XPath2 for .NET
Microsoft Public License
36 stars 14 forks source link

Wrong result with XPath2.0 function usage #58

Closed Vadim2S closed 1 year ago

Vadim2S commented 2 years ago

XML:

<R>
<A id="1"/>
<A id="2"/>
</R>

XPath: /R/A[@id=max(/R/A/@id)]

Expected result: <A id="2"/>

Actual result: none.

max(/R/A/@id) returns 2.

StefH commented 1 year ago

@Vadim2S max can only be used on a number, in your case the max(/R/A/@id) returns a a string.

Solution : convert to number first

/R/A[@id=max(/R/A/number(@id))]

Or for safety, convert the result from the max also to string: /R/A[@id=string(max(/R/A/number(@id)))]

Vadim2S commented 1 year ago

Sorry, but I am not understand this number trick.

As I am wrote before: standalone xpath max(/R/A/number(@id)) works perfectly! It is return right max result "2".

Even if you right - there must be evaluation: /R/A[@id="2"] with string "2". It is correct xpath and must return expected result . Not None.

Conclusion: max() work standalone but do not work inside another xpath.

P.S. Other XPath processors like Saxon or XMLSpy buildin - get expected result.

StefH commented 1 year ago

https://github.com/StefH/XPath2.Net/pull/61

StefH commented 1 year ago

@Vadim2S You are correct, this should work but does not work correctly it seems. Exception like "System.Xml.XPath.XPathException : Namespace Manager or XsltContext needed. This query has a prefix, variable, or user-defined function.".

The only solution for you is to use a different xpath expression.

This one works:

"/R/A[not(/R/A/@id > @id)]"

(based on https://stackoverflow.com/questions/3786443/xpath-to-get-the-element-with-the-highest-id)