XDocument के साथ XPath का उपयोग कैसे करें?


109

इसी तरह का सवाल है, लेकिन ऐसा लगता है कि समाधान मेरे मामले में कारगर नहीं हुआ : एक्सडजस्टमेंट, एक्सपीथ और नेमस्पेस के साथ अजीबता

यहाँ XML के साथ मैं काम कर रहा हूँ:

<?xml version="1.0" encoding="utf-8"?>
<Report Id="ID1" Type="Demo Report" Created="2011-01-01T01:01:01+11:00" Culture="en" xmlns="http://demo.com/2011/demo-schema">
    <ReportInfo>
        <Name>Demo Report</Name>
        <CreatedBy>Unit Test</CreatedBy>
    </ReportInfo>
</Report>

और नीचे कोड है कि मुझे लगा कि यह काम करना चाहिए, लेकिन यह नहीं था ...

XDocument xdoc = XDocument.Load(@"C:\SampleXML.xml");
XmlNamespaceManager xnm = new XmlNamespaceManager(new NameTable()); 
xnm.AddNamespace(String.Empty, "http://demo.com/2011/demo-schema");
Console.WriteLine(xdoc.XPathSelectElement("/Report/ReportInfo/Name", xnm) == null);

क्या किसी के पास कोई विचार है? धन्यवाद।


1
नीचे दिए गए अन्य उत्तर को देखें, यह काम नहीं करता क्योंकि XPath 1.0 कार्यान्वयन एक खाली उपसर्ग के साथ सामना नहीं कर सकता
पॉल हैचर

1
जैसा कि अन्य ने यहां कहा है, [XmlNamespaceManager] में एक Namespace जोड़ते समय एक खाली उपसर्ग का उपयोग न करें। मैं सिर्फ इस टिप्पणी को जोड़ रहा हूं कि कोई भी एक दस्तावेज के साथ एक छोटा कोड उदाहरण देखना चाहता है जिसमें कई [xmlns] विशेषताएँ हैं, जो एक प्रत्यय के साथ और उसके बिना हैं। यहां देखें: stackoverflow.com/a/38272604/5838538
जेलगैब

जवाबों:


158

यदि आपके पास XDocument है तो LINQ-to-XML का उपयोग करना आसान है:

var document = XDocument.Load(fileName);
var name = document.Descendants(XName.Get("Name", @"http://demo.com/2011/demo-schema")).First().Value;

यदि आप सुनिश्चित हैं कि XPath आपके लिए एकमात्र समाधान है:

using System.Xml.XPath;

var document = XDocument.Load(fileName);
var namespaceManager = new XmlNamespaceManager(new NameTable());
namespaceManager.AddNamespace("empty", "http://demo.com/2011/demo-schema");
var name = document.XPathSelectElement("/empty:Report/empty:ReportInfo/empty:Name", namespaceManager).Value;

13
मैं कहूंगा कि ज्यादातर मामलों में लिनपैक के मुकाबले लाइनक को कहना मुश्किल है। उदाहरण के लिए इस मामले में LINQ समतुल्य नहीं है, क्योंकि यह अन्य नोड्स के तहत "नाम" नोड्स भी प्राप्त करेगा (जो अभी वहां नहीं हैं लेकिन फ़ाइल के प्रारूप में बाद के बदलावों से जोड़े जा सकते हैं)। हालाँकि आपका समाधान निश्चित रूप से सही है।
मार्को एमपी

12
नोट: का उपयोग कर System.Xml.XPath; बहुत महत्वपूर्ण है क्योंकि XPathSelectElement एक विस्तार विधि है। जैसा मैंने किया और उस भाग को अनदेखा नहीं किया;)
मार्क वैन स्ट्रैटन

7
XPath अभी भी इसमें सहायक है कि यह आपको अपने माता-पिता के बाल संबंधों को प्रासंगिक बनाने की अनुमति देता है। जैसे अगर आप हर केले को पाने के बजाय केले / केले / केला / केले को पाना चाहते हैं
सेबस्टियन पैटन

2
"खाली" यहाँ थोड़ा भ्रामक और भ्रमित करने वाला है। आप XPath, String.Empty (खोजकर्ता के रूप में खोजा गया) के अलावा कुछ भी उपयोग कर सकते हैं। "डेमो" उदाहरण के लिए अधिक उपयुक्त होगा।
टॉम ब्लोडेट

7

XPath 1.0, जो कि एमएस लागू करता है, को डिफ़ॉल्ट नाम स्थान का विचार नहीं है। तो यह प्रयास करें:

XDocument xdoc = XDocument.Load(@"C:\SampleXML.xml");
XmlNamespaceManager xnm = new XmlNamespaceManager(new NameTable()); 
xnm.AddNamespace("x", "http://demo.com/2011/demo-schema");
Console.WriteLine(xdoc.XPathSelectElement("/x:Report/x:ReportInfo/x:Name", xnm) == null);

8
आपका उत्तर यह बताता है कि XPath 2.0, XPath 1.0 के विपरीत "* में एक डिफ़ॉल्ट नामस्थान का" एक विचार "है। मुझे ऐसी नई XPath सुविधा के बारे में पता नहीं है (हम यहां XPath की बात कर रहे हैं, XSLT या XQuery की नहीं।) इसलिए, क्या आप कर सकते हैं।" , कृपया अपने उत्तर में स्पष्ट रूप से उल्लेख करें कि आप क्या कर रहे हैं?
दिमित्रे नोवत्चेव

2
मुझे लगता है कि वह यहाँ क्या कर रहा है, यदि आपके पास एक दस्तावेज है जो किसी नाम स्थान को परिभाषित करता है, तो आपके xpath में योग्य तत्व शामिल होने चाहिए, यानी आप xnm.AddNamespace (string.Empty, "Demo.com/2011/ememo-schema" नहीं कर सकते हैं ) ); और फिर xdoc.XPathSelectElement ("/ रिपोर्ट / ReportInfo / नाम", xnm) - परिणाम हमेशा शून्य से बाहर आता है
पॉल हैचर

3

आप Microsoft से उदाहरण का उपयोग कर सकते हैं - आपके लिए बिना नामस्थान के:

using System.Xml.Linq;
using System.Xml.XPath;
var e = xdoc.XPathSelectElement("./Report/ReportInfo/Name");     

करना चाहिए


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