Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the node with min attribute value?

My xml structure is something like this :

<page height="777" width="777">
    <block r="777" l="778" blockType="Text">
        <region/>
        <separator/>
    </block>
    <block r="777" l="790" blockType="Text">
        <region/>
        <separator/>
    </block>
    <block r="777" l="688" blockType="Text">
        <region/>
        <text/>
    </block>
</page>

i want the select the block node which has the min "l" value i.e "688"

I know there is a min() function available in XPath 2.0, but i am using Xpath1.0.

I tried this

     //XPathExpression pattern2TextExpr = 
xPath.compile("//page/block[not(preceding-sibling::block/@l < = @l) and not(following-sibling::block/@l >@l)]/@l");

How can I use XPath to find the minimum value of an attribute in a set of elements?

But this gives me multiple nodelist. if it's min it should be only one node. Any other possible and efficient solution to this ?? Please suggest. Thanks

like image 806
Maverick Avatar asked Mar 09 '26 23:03

Maverick


1 Answers

UPDATE 2:

According to the updated XML sample, assuming that you want to find minimum value of l attribute of line element, try this way :

//page/block/text/par/line[not(preceding::line/@l <= @l) and not(following::line/@l<@l)]/@l

output :

Attribute='l="253"'

UPDATE :

Actually, by having combination of preceding-sibling::block/@l <= @l and following-sibling::block/@l < @l, there is no chance you get duplicate anyway. The xpath returns only the first minimum value in case of duplicate values exists, because of <=. The real problem I found in your xpath is, that you use > in the following-sibling evaluation instead of using <.

 //page/block[
        not(preceding-sibling::block/@l <= @l) 
            and 
        not(following-sibling::block/@l < @l)
    ]/@l

But this gives me multiple nodelist. if it's min it should be only one node.

If the only catch is that your xpath may return multiple values, then you can simply wrap the entire xpath with ()[1] to limit the result to single value, for example (formatted for readability) :

(
 //page/block[
        not(preceding-sibling::block/@l <= @l) 
            and 
        not(following-sibling::block/@l > @l)
    ]/@l
)[1]

output in xpath tester :

Attribute='l="688"'
like image 198
har07 Avatar answered Mar 11 '26 12:03

har07



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!