Xpath का उपयोग करके नोड की स्थिति ज्ञात करें


86

किसी को पता है कि xpath का उपयोग करके नोड की स्थिति कैसे प्राप्त करें?

कहो मेरे पास निम्नलिखित xml है:

<a>
    <b>zyx</b>
    <b>wvu</b>
    <b>tsr</b>
    <b>qpo</b>
</a>

मैं तीसरे <b> नोड (<b> tsr </ b>) का चयन करने के लिए निम्नलिखित xpath क्वेरी का उपयोग कर सकता हूं:

a/b[.='tsr']

जो सब ठीक है और अच्छा है, लेकिन मैं उस नोड की क्रमिक स्थिति को वापस करना चाहता हूं , जैसे कुछ:

a/b[.='tsr']/position()

(लेकिन थोड़ा और अधिक काम!)

क्या यह भी संभव है?

संपादित करें : .net 2 का उपयोग करना भूल गए इसलिए यह xpath 1.0 है!


अद्यतन : जेम्स सुलक के उत्कृष्ट उत्तर का उपयोग करके समाप्त किया गया । उन लोगों के लिए जो C # में मेरे कार्यान्वयन में रुचि रखते हैं:

int position = doc.SelectNodes("a/b[.='tsr']/preceding-sibling::b").Count + 1;

// Check the node actually exists
if (position > 1 || doc.SelectSingleNode("a/b[.='tsr']") != null)
{
    Console.WriteLine("Found at position = {0}", position);
}

कृपया प्रश्न में उत्तर पोस्ट न करने का प्रयास करें -> बेहतर होगा कि इसे उत्तर के रूप में पोस्ट किया जाए, फिर संभवतः इसे प्रश्न से जोड़ा जाए।
theMayer

जवाबों:


94

प्रयत्न:

count(a/b[.='tsr']/preceding-sibling::*)+1.

1
'Coz मैं उपयोग कर रहा हूँ .net या तो यह या मैं अपने साथ गई शक्ति को संभाल नहीं सकता: int position = doc.SelectNodes ("a / b [। =' Tsr '] / preceding-Sibling :: b") .काउंट + 1 if (स्थिति> 1) doc.SelectSingleNode ("a / b [। = tsr]]]") =! null) // नोड की जाँच करें वास्तव में मौजूद है // // यहाँ जादू करें
Wilfred Knievelle

शून्य अनुक्रमित भाषाओं में आपको
जॉनी रा

9

आप इसे XSLT के साथ कर सकते हैं लेकिन मुझे सीधे XPath के बारे में निश्चित नहीं है।

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" encoding="utf-8" indent="yes" 
              omit-xml-declaration="yes"/>
  <xsl:template match="a/*[text()='tsr']">
    <xsl:number value-of="position()"/>
  </xsl:template>
  <xsl:template match="text()"/>
</xsl:stylesheet>

9

मुझे एहसास है कि पद प्राचीन है .. लेकिन ..

nodename के साथ तारांकन को बदलने से आपको बेहतर परिणाम मिलेंगे

count(a/b[.='tsr']/preceding::a)+1.

के बजाय

count(a/b[.='tsr']/preceding::*)+1.

4

यदि आप कभी भी XPath 2.0 में अपग्रेड करते हैं, तो ध्यान दें कि यह फ़ंक्शन इंडेक्स-इन प्रदान करता है , यह समस्या को हल करता है:

index-of(//b, //b[.='tsr'])

कहाँ पे:

  • 1 पैरामीटर खोज के लिए अनुक्रम है
  • 2 क्या खोजना है

यह ध्यान दिया जाना चाहिए कि यह केवल XPath 2+ के साथ काम करेगा। नीचे कुछ भी 'अजीब' गिनती फ़ंक्शन का उपयोग करना होगा।
डान एटकिंसन

1
@, यह मूल डॉक्स के लिंक में नोट किया गया था, स्पष्ट सूचना, धन्यवाद!
क्रोवेल

3

पहले से कहा गया 'पूर्ववर्ती-भाई-बहन' वास्तव में उपयोग करने के लिए धुरी है, न कि 'पूर्ववर्ती' जो पूरी तरह से कुछ अलग करता है, यह उस दस्तावेज़ में सब कुछ चुनता है जो वर्तमान नोड के प्रारंभ टैग से पहले है। (देखें http://www.w3schools.com/xpath/xpath_axes.asp )


4
पूर्वज नोड्स सहित नहीं। विवरण पर w3schools पर भरोसा मत करो! लेकिन मैं सहमत हूं ... हालांकि पूर्ववर्ती :: इस मामले में काम करता है, क्योंकि पूर्वज के अलावा प्रासंगिक बी तत्वों से पहले कोई तत्व नहीं हैं, यह पूर्ववर्ती-भाई-बहन की तुलना में अधिक नाजुक है। ओटीओएच, ओपी ने हमें यह नहीं बताया कि वह किस संदर्भ में स्थिति जानना चाहते हैं, इसलिए संभावित रूप से पूर्ववर्ती :: सही हो सकता है।
लार्ष

2

जेम्स सुलक द्वारा किए गए उत्तर पर ध्यान दें।

यदि आप इस बात को ध्यान में रखना चाहते हैं कि नोड मौजूद नहीं हो सकता है और इसे विशुद्ध रूप से XPATH रखना चाहते हैं, तो कोशिश करें कि नोड मौजूद नहीं होने पर 0 वापस आ जाएगा।

count(a/b[.='tsr']/preceding-sibling::*)+number(boolean(a/b[.='tsr']))

0

समस्या यह है कि नोड की स्थिति एक संदर्भ के बिना ज्यादा मायने नहीं रखती है।

निम्न कोड आपको इसके मूल बच्चे नोड्स में नोड का स्थान देगा

using System;
using System.Xml;

public class XpathFinder
{
    public static void Main(string[] args)
    {
        XmlDocument xmldoc = new XmlDocument();
        xmldoc.Load(args[0]);
        foreach ( XmlNode xn in xmldoc.SelectNodes(args[1]) )
        {
            for (int i = 0; i < xn.ParentNode.ChildNodes.Count; i++)
            {
                if ( xn.ParentNode.ChildNodes[i].Equals( xn ) )
                {
                    Console.Out.WriteLine( i );
                    break;
                }
            }
        }
    }
}

1
तो अब वास्तव में एक XPath खोजक नहीं है, लेकिन एक C # खोजक है।
रमेश

0

मैं नोवेल आइडेंटिटी मैनेजर का बहुत सारा सामान करता हूं, और उस संदर्भ में XPATH थोड़ा अलग दिखता है।

मान लें जो आप देख रहे हैं वह एक स्ट्रिंग चर में है, जिसे TARGET कहा जाता है, तो XPATH होगा:

count(attr/value[.='$TARGET']/preceding-sibling::*)+1

इसके अतिरिक्त यह बताया गया था कि अंतरिक्ष के कुछ पात्रों को बचाने के लिए, निम्नलिखित भी काम करेगा:

count(attr/value[.='$TARGET']/preceding::*) + 1

मैंने नॉवेल के कूल सॉल्यूशंस में इसका एक प्रिटियर वर्जन भी पोस्ट किया है: पोजिशन नोड पाने के लिए XPATH का उपयोग करना

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.