How to find the max attribute from an XML document using Xpath 1.0

后端 未结 7 1010
无人及你
无人及你 2020-11-29 10:43

Is there a way to query an XML document to return the maximum of a given attribute using Xpath 1.0 ?

For example is there a way to get the max id ?

&         


        
相关标签:
7条回答
  • 2020-11-29 10:47

    XPath 1.0

    /library/book[not(@id < /library/book/@id)]
    

    This query style is more generic and works even if books are grouped i.e.

    <?xml version="1.0" encoding="utf-8"?>
    <library>
        <genre id="1">
            <book id="2" name="Dragon Tatoo"/>
            <book id="7" name="Ender's Game"/>
        </genre>
        <genre id="2">
            <book id="3" name="Catch 22"/>
            <book id="1" name="Lord of the rings"/>
        </genre>
    </library>
    

    Same query still works (the path should be modified)

    /library/genre/book[not(@id < /library/genre/book/@id)]
    

    or even

    //book[not(@id < //book/@id)]
    

    To avoid performance troubles use XPath 2 max() instead

    0 讨论(0)
  • 2020-11-29 10:51

    If you're willing to use external tooling - which depends on your implementation featuring implementations of these tools - try the EXSLT:Math function highest().

    The fact that EXSLT implements this implies that such a feature isn't directly available in plain xpath, of course. If you're not using Transforms, or want to stick purely with standards-compliant markup, other posters' suggestions would be a better choice.

    0 讨论(0)
  • 2020-11-29 10:52

    This example can be used to find the max.

    XmlDocument doc = new XmlDocument();                    
    doc.Load("../../Employees.xml");
    XmlNode node = doc.SelectSingleNode("//Employees/Employee/@Id[not(. <=../preceding-sibling::Employee/@id) and not(. <=../following-sibling::Employee/@Id)]");
    int maxId = Convert.ToInt32(node.Value);
    

    For other similar topics on xpath and linq check out http://rmanimaran.wordpress.com/2011/03/20/xml-find-max-and-min-value-in-a-attribute-using-xpath-and-linq/

    0 讨论(0)
  • 2020-11-29 10:55

    The following XPath selects the book with highest id:

    /library/book[not(@id <= preceding-sibling::book/@id) and not(@id <=following-sibling::book/@id)]
    
    0 讨论(0)
  • 2020-11-29 10:58

    In XPath 2.0, use the max function. To find the book with the highest id, do

    /library/book[@id = max(/library/book/@id)]
    
    0 讨论(0)
  • 2020-11-29 11:06

    I've found that answers like the lwburk's or timbooo's work fine for attributes representing numbers having just one digit. However, if the attribute is a number having more than one digit, extrange things seem to happen when comparing between attributes' values. For example, try changing the original XML data with something like this:

    <?xml version="1.0" encoding="utf-8"?>
    <library>
            <book id="250" name="Dragon Tatoo"/>
            <book id="700123" name="Ender's Game"/>
            <book id="305" name="Catch 22"/>
            <book id="1070" name="Lord of the rings"/>
    </library>
    

    Running the suggested snippets won't work. I got a solution using the casting operator xs:int() applied on id attribute, like in:

    /library/book[not(xs:int(@id) <= preceding-sibling::book/@id) and not(xs:int(@id) <=following-sibling::book/@id)]
    

    That will give the correct answer!

    0 讨论(0)
提交回复
热议问题