2012-01-02 14 views
7

का उपयोग कर किसी XML दस्तावेज़ से अधिकतम विशेषता को कैसे प्राप्त करें Xpath 1.0 का उपयोग करके दिए गए किसी भी विशेषता को वापस करने के लिए XML दस्तावेज़ से पूछताछ करने का कोई तरीका है?Xpath 1.0

उदाहरण के लिए अधिकतम आईडी प्राप्त करने का कोई तरीका है?

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

+1, अनानस के लिए: पी –

+0

XPath निष्पादित करने के लिए आपकी मेजबान भाषा क्या है? यदि आप XPath 1.0 का उपयोग कर रहे हैं (जिसमें 'अधिकतम' फ़ंक्शन नहीं है) तो पहले सभी तत्वों का चयन करने और अपने पीएल में अधिकतम खोजने के लिए शायद तेज़ है। –

+0

मैं पर्ल 5.10 का उपयोग कर रहा हूं। – HerbSpiral

उत्तर

0

इस उदाहरण का उपयोग अधिकतम खोजने के लिए किया जा सकता है।

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); 

xpath और LINQ पर जैसे अन्य विषयों के लिए बाहर की जाँच http://rmanimaran.wordpress.com/2011/03/20/xml-find-max-and-min-value-in-a-attribute-using-xpath-and-linq/

3

निम्नलिखित XPath उच्चतम आईडी के साथ पुस्तक का चयन करता है:

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

यह वास्तव में काम करता है, हालांकि प्रदर्शन अच्छा नहीं है (जब दस्तावेज़ में हजारों आईडी मौजूद हैं) – HerbSpiral

+0

+1 - मैंने आपके उत्तर का मूल दोहराया, लेकिन मैं बस अपने उत्तर में अतिरिक्त जानकारी प्रदान करना चाहता था, जिनमें से कुछ टिप्पणियों के आसपास क्या फैल गया है। –

+0

@lwburk कोई समस्या नहीं;) – timbooo

2

आप बाहरी टूलींग उपयोग करने के लिए तैयार हैं, तो - जो इन उपकरणों के कार्यान्वयन की विशेषता वाले आपके कार्यान्वयन पर निर्भर करता है - EXSLT:Math फ़ंक्शन highest() पर आज़माएं।

तथ्य यह है कि EXSLT लागू करता है यह दर्शाता है कि ऐसी सुविधा सीधे सादा xpath में उपलब्ध नहीं है। यदि आप ट्रांसफॉर्म का उपयोग नहीं कर रहे हैं, या मानक-अनुरूप मार्कअप के साथ पूरी तरह से चिपकना चाहते हैं, तो अन्य पोस्टर्स के सुझाव बेहतर विकल्प होंगे।

7

XPath 2.0 में, max फ़ंक्शन का उपयोग करें। उच्चतम id साथ किताब खोजने के लिए, कर

/library/book[@id = max(/library/book/@id)] 
+1

लगता है कि अधिकतम फ़ंक्शन Xpath 1.0 का हिस्सा नहीं है :( – HerbSpiral

+0

@HerbSpiral: hmm। XQilla XPath 1.0 compat मोड में इसका प्रयास किया और यह काम करता है , लेकिन शायद यह वास्तव में XPath 1.0 नहीं है। –

2

नोट: निम्न जानकारी XPath 1.0 के उपयोग मान लिया गया है।

निम्नलिखित अभिव्यक्ति सबसे बड़ा id मूल्य के साथ तत्व (रों) देता है:

/*/book[not(@id < preceding-sibling::book/@id) and 
     not(@id < following-sibling::book/@id)] 

ध्यान दें कि यह थोड़ा अलग से है कि में @ timbooo का जवाब जब वहाँ के साथ डुप्लिकेट हैं इस एक से अधिक तत्व वापस आ जाएगी है वही अधिकतम मूल्य (@ timbooo कोई भी वापस नहीं करेगा)। यदि आप इस मामले में केवल एक तत्व चाहते हैं, तो आपको एक रिज़ॉल्यूशन रणनीति की आवश्यकता है। दस्तावेज़ के क्रम में इस तरह की पहली तत्व का चयन करने के लिए, इस का उपयोग करें:

/*/book[not(@id < preceding-sibling::book/@id) and 
     not(@id < following-sibling::book/@id)][1] 

पिछले एक का चयन करने के लिए, इस का उपयोग करें:

/*/book[not(@id < preceding-sibling::book/@id) and 
     not(@id < following-sibling::book/@id)][last()] 

यह दृष्टिकोण बहुत अक्षम (O(n^2)) क्योंकि यह तुलना करने के लिए आप की आवश्यकता है प्रत्येक तत्व प्रत्येक अन्य संभावित अधिकतम करने के लिए। इस कारण से, अधिकतम तत्व का चयन करने के लिए शायद अपनी मेजबान प्रोग्रामिंग भाषा का उपयोग करना सबसे अच्छा है। बस पहले book तत्वों का चयन करें और फिर उस सूची से अधिकतम चुनें। यह (सबसे अधिक संभावना) एक रैखिक ऑपरेशन (O(n)) है, जो बहुत बड़े दस्तावेज़ों पर काफी तेजी से होगा। उदाहरण के लिए, जावा (JAXP) में आप इसे इस प्रकार कर सकते हैं:

XPath xpath = XPathFactory.newInstance().newXPath(); 
NodeList nodes = (NodeList) xpath.evaluate("/*/book", doc, 
     XPathConstants.NODESET); 
Node max = nodes.item(0); 
for (int i = 0; i < nodes.getLength(); i++) { 
    int maxval = Integer.parseInt(max.getAttributes() 
      .getNamedItem("id").getNodeValue()); 
    int curval = Integer.parseInt(nodes.item(i).getAttributes() 
      .getNamedItem("id").getNodeValue()); 
    if (curval >= maxval) 
     max = nodes.item(i); 
} 
System.out.println(max.getAttributes().getNamedItem("name")); 

ध्यान दें कि यह सिर्फ एक प्रदर्शन है; जहां उचित हो वहां नल-चेक शामिल करना सुनिश्चित करें।

1

मुझे पता चला है कि lwburk या timbooo के काम ठीक है जैसे संख्याओं का प्रतिनिधित्व करने वाले गुणों के लिए केवल एक अंक है। हालांकि, यदि विशेषता एक संख्या से अधिक अंक वाली संख्या है, तो विशेषताएँ मानों के बीच तुलना करते समय चीजें घटित होती हैं। उदाहरण के लिए, कुछ इस तरह के साथ मूल XML डेटा बदलने का प्रयास करें:

<?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> 

सुझाव के टुकड़े काम नहीं करेगा चल रहा है। मैं कास्टिंग ऑपरेटर XS का उपयोग कर एक समाधान मिल गया: पूर्णांक() में की तरह, आईडी गुण पर लागू:

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

कि सही जवाब दे देंगे!