How to get the node with min attribute value?

211 views Asked by At

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

3

There are 3 answers

7
har07 On BEST ANSWER

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"'
0
Maverick On

Here's the Xml which i am using. The above xpath always returns the first element.

line b="240" r="1148" t="208" l="1026"

<page originalCoords="1" resolution="300" height="3641" width="2656">
-<block b="246" r="1154" t="207" l="1020" blockName="" blockType="Text">
-<text>
-<par lineSpacing="890">
-<line b="240" r="1148" t="208" l="1026" baseline="280">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
</text>
</block>
-<block b="259" r="1540" t="215" l="1336" blockName="" blockType="Text">
-<text>
-<par lineSpacing="890">
-<line b="252" r="1534" t="217" l="1342" baseline="282">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
</text>
</block>
-<block b="303" r="2510" t="235" l="2075" blockName="" blockType="Text">
-<region>
<rect b="236" r="2104" t="235" l="2076"/>
<rect b="237" r="2142" t="236" l="2076"/>
<rect b="238" r="2180" t="237" l="2076"/>
</region>
-<text>
-<par lineSpacing="1000">
-<line b="289" r="2504" t="237" l="2081" baseline="283">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
</text>
</block>
-<block b="966" r="1607" t="191" l="232" blockName="" blockType="Text">
-<text>
-<par lineSpacing="890" align="Justified">
-<line b="252" r="790" t="198" l="258" baseline="287">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
</text>
-<text>
-<par lineSpacing="1230" align="Justified" leftIndent="900">
-<line b="298" r="841" t="243" l="272" baseline="339">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
-<par lineSpacing="984">
-<line b="370" r="1479" t="299" l="255" baseline="394">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
-<line b="424" r="1605" t="343" l="253" baseline="435">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
-<par lineSpacing="1224" align="Justified" leftIndent="900">
-<line b="467" r="1581" t="395" l="282" baseline="489">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
-<par lineSpacing="1224" align="Justified" leftIndent="900">
-<line b="521" r="1580" t="446" l="281" baseline="540">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
-<par lineSpacing="1224" align="Justified" leftIndent="900">
-<line b="565" r="1578" t="497" l="282" baseline="591">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
-<par lineSpacing="1200" align="Justified" leftIndent="900">
-<line b="618" r="1577" t="546" l="278" baseline="638">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
-<par lineSpacing="1200" align="Justified" leftIndent="900">
-<line b="667" r="1576" t="596" l="278" baseline="688">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
-<par lineSpacing="1200" align="Justified" leftIndent="900">
-<line b="718" r="1573" t="644" l="277" baseline="738">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
-<par lineSpacing="1200" align="Justified" leftIndent="900">
-<line b="758" r="1481" t="695" l="276" baseline="788">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
-<par lineSpacing="1200" align="Justified" leftIndent="900">
-<line b="818" r="1583" t="744" l="274" baseline="837">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
-<par lineSpacing="1200" align="Justified" leftIndent="900">
-<line b="870" r="1587" t="794" l="273" baseline="889">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
-<par lineSpacing="950" align="Justified" leftIndent="900">
-<line b="916" r="1580" t="842" l="272" baseline="934">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
-<par lineSpacing="950" align="Justified" leftIndent="900">
-<line b="960" r="1579" t="892" l="269" baseline="983">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
</text>
</block>
-<block b="756" r="1748" t="428" l="1686" blockName="" blockType="Text">
-<text>
-<par lineSpacing="1360" align="Justified">
-<line b="477" r="1748" t="434" l="1694" baseline="499">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
-<par lineSpacing="1060" align="Justified">
-<line b="516" r="1740" t="484" l="1700" baseline="541">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
-<par lineSpacing="950" align="Justified">
-<line b="563" r="1737" t="532" l="1699" baseline="587">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
-<par lineSpacing="1176" align="Justified">
-<line b="608" r="1738" t="578" l="1697" baseline="632">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
-<line b="666" r="1743" t="627" l="1696" baseline="680">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
-<par lineSpacing="950" align="Justified">
-<line b="714" r="1742" t="672" l="1688" baseline="738">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
-<par lineSpacing="950" align="Justified">
-<line b="750" r="1732" t="720" l="1694" baseline="774">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
</text>
</block>
-<block b="575" r="2129" t="355" l="1797" blockName="" blockType="Text">
-<text>
-<par lineSpacing="1170" leftIndent="1100">
-<line b="405" r="2055" t="362" l="1847" baseline="414">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
-<par lineSpacing="1200" align="Justified">
-<line b="466" r="2003" t="421" l="1800" baseline="481">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
-<par lineSpacing="1200" align="Justified">
-<line b="522" r="2120" t="471" l="1802" baseline="534">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
-<par lineSpacing="1200" align="Right">
-<line b="569" r="2119" t="522" l="1883" baseline="579">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
</text>
</block>
-<block b="421" r="2436" t="367" l="2215" blockName="" blockType="Text">
-<text>
-<par lineSpacing="950">
-<line b="415" r="2430" t="373" l="2221" baseline="414">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
</text>
</block>
-<block b="585" r="2494" t="496" l="2403" blockName="" blockType="Text">
-<text>
-<par lineSpacing="890">
-<line b="531" r="2488" t="502" l="2412" baseline="535">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
-<par lineSpacing="890">
-<line b="579" r="2487" t="552" l="2409" baseline="582">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
</text>
</block>
-<block b="766" r="2125" t="563" l="1894" blockName="" blockType="Text">
-<text>
-<par lineSpacing="890" align="Justified">
-<line b="616" r="2117" t="568" l="1904" baseline="624">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
-<par lineSpacing="1128" align="Justified">
-<line b="676" r="2117" t="625" l="1897" baseline="676">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
-<par lineSpacing="1128" align="Right">
-<line b="712" r="2117" t="665" l="1980" baseline="725">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
-<line b="760" r="2115" t="718" l="1900" baseline="770">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
</text>
</block>
-<block b="776" r="2493" t="591" l="2399" blockName="" blockType="Text">
-<text>
-<par lineSpacing="1120" align="Justified">
-<line b="640" r="2485" t="597" l="2403" baseline="631">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
-<par lineSpacing="1152" align="Justified">
-<line b="675" r="2484" t="646" l="2408" baseline="677">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
-<par lineSpacing="1152" align="Justified">
-<line b="722" r="2483" t="693" l="2407" baseline="726">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
-<par lineSpacing="1152" align="Justified">
-<line b="770" r="2483" t="742" l="2407" baseline="774">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
</text>
</block>
-<block b="935" r="2336" t="775" l="2185" blockName="" blockType="Text">
-<text>
-<par lineSpacing="1360" align="Justified">
-<line b="838" r="2328" t="780" l="2202" baseline="846">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
-<par lineSpacing="1296" align="Justified">
-<line b="889" r="2326" t="841" l="2199" baseline="886">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
-<line b="935" r="2327" t="877" l="2208" baseline="938">
<formatting lang="EnglishUnitedStates">data scrambled</formatting>
</line>
</par>
</text>
</block>
</page>
0
mkanugan On

Please use the below code and already known solution for xpath 1.0, please see the link here How can I use XPath to find the minimum value of an attribute in a set of elements?

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