2009-07-15 12 views
27

अगर मैं है की तरह एक्सएमएल:तत्वों के एक समूह में किसी विशेषता के न्यूनतम मान को खोजने के लिए मैं XPath का उपयोग कैसे कर सकता हूं?

<foo> 
    <bar id="1" score="192" /> 
    <bar id="2" score="227" /> 
    <bar id="3" score="105" /> 
    ... 
</foo> 

मैं XPath न्यूनतम और score की अधिकतम मूल्यों को खोजने के लिए उपयोग कर सकते हैं?

संपादित करें: मैं जिस उपकरण का उपयोग कर रहा हूं (Andariel चींटी कार्य) XPath 2.0 समाधान का समर्थन नहीं करता है।

उत्तर

16

उपकरण XPath 2.0 का समर्थन नहीं करता बाहर कर देता है।

XPath 1.0 फैंसी min() और max() कार्यों इसलिए इन मूल्यों को हम XPath तर्क के साथ एक छोटे से मुश्किल होने की जरूरत है खोजने के लिए नहीं है, तथा नोड के भाई-बहन पर मूल्यों की तुलना:

अधिकतम :

/foo/bar[not(preceding-sibling::bar/@score >= @score) 
    and not(following-sibling::bar/@score > @score)]/@score 

न्यूनतम:

/foo/bar[not(preceding-sibling::bar/@score <= @score) 
    and not(following-sibling::bar/@score < @score)]/@score 

तो XSLT या चींटी की तरह एक्सएमएल फाइल में इन प्रश्नों embedding cripts, &lt; सम्मान &gt; रूप < और > एन्कोड करने के लिए याद है।

+0

अच्छा काम! मैंने पहले शीर्ष रैंकिंग समाधान की कोशिश की लेकिन वह डुप्लिकेट maxima/minima को बाहर नहीं करता है। – udo

5

यह काम करना चाहिए ...

max(foo/bar/@score) 

... और ...

min(foo/bar/@score) 

... इस function reference की जाँच करें।

+0

ठीक है। यह XPath 2.0 है, मैं इसे देख लूंगा। – brasskazoo

+0

हां, XPath 2.0। –

3

इस प्रयास करें:

//foo/bar[not(preceding-sibling::bar/@score <= @score) and not(following-sibling::bar/@score <= @score)] 

हो सकता है कि यह XPath 1.0 पर काम करेंगे।

36

यहां थोड़ा छोटा समाधान है।

अधिकतम:

/foo/bar/@score[not(. < ../../bar/@score)][1] 

न्यूनतम:

/foo/bar/@score[not(. > ../../bar/@score)][1] 

मैं विधेय संपादित किया है इतना है कि यह bar के किसी भी क्रम प्रकार लागू होता है, भले ही आप पथ को बदलने का फैसला। ध्यान दें कि विशेषता का अभिभावक वह तत्व है जिसके लिए यह संबंधित है।

तो XSLT या चींटी स्क्रिप्ट की तरह एक्सएमएल फाइल में इन प्रश्नों embedding, &lt; सम्मान &gt; रूप < और > एन्कोड करने के लिए याद है।

+0

कूल ... लेकिन मैं गारंटी नहीं दे सकता कि वहां 'स्कोर' के एकाधिक अधिकतम मान नहीं होंगे (उदाहरण के लिए)। यह प्रत्येक तत्व के लिए एक मान सूचीबद्ध करेगा जिसमें अधिकतम .. – brasskazoo

+1

सत्य - उस के लिए खाते में संपादित किया गया है। –

+0

शायद आप 'संख्या (।)' का उपयोग करना चाहते हैं क्योंकि अन्यथा यह गुणों के स्ट्रिंग मानों की तुलना करता है। क्या मैं सही हू? – DanSkeel

4

मैं धागा पर ठोकर खाई और एक जवाब है कि मेरे लिए काम किया नहीं मिल रहा था, इसलिए जहां मैं क्या अंततः का उपयोग कर समाप्त हो गया है ...

आउटपुट न्यूनतम मूल्य, बेशक आप उत्पादन के लिए चुन सकते हैं आपके द्वारा चुने गए सबसे कम मूल्य वाले नोड से @id।

<xsl:for-each select="/foo"> 
    <xsl:sort select="@score"/> 
    <xsl:if test="position()=1"> 
    <xsl:value-of select="@score"/> 
    </xsl:if> 
</xsl:for-each> 

अधिकतम मूल्य के लिए एक ही:

<xsl:for-each select="/foo"> 
    <xsl:sort select="@score" order="descending"/> 
    <xsl:if test="position()=1"> 
    <xsl:value-of select="@score"/> 
    </xsl:if> 
</xsl:for-each> 
3

मैं जानता हूँ कि इस पांच साल पुराना है। जो भी खोज सकता है और इस पर आ सकता है, उसके लिए बस कुछ और विकल्प जोड़ना।

इस तरह से कुछ इसी तरह XSLT 2.0 में मेरे लिए काम करता है।

min(//bar[@score !='']/@score) 

!='' एक nulls जो NaN मूल्यों लाया से बचने के लिए था

यहाँ है (वहाँ शायद ऐसा करने के लिए एक बेहतर तरीका है) एक काम xpath/XQuery:

//bar/@score[@score=min(//*[@score !='']/number(@score))]