2013-04-15 8 views
13

के साथ प्रश्न XDocument क्वेरी दृश्य स्टूडियो * .csproj फ़ाइल से तत्वों से पूछने का प्रयास करें। मैंने समस्या का वर्णन करने के लिए एक छोटा सा उदाहरण बनाया:xmlns विशेषता (नेमस्पेस)

// Working 
    string xml1 = @"<Project ToolsVersion='4.0'> 
         <ItemGroup Label='Usings'> 
         <Reference Include='System' /> 
         <Reference Include='System.Xml' /> 
         </ItemGroup> 
        </Project>"; 
    // Not working 
    string xml2 = @"<Project ToolsVersion='4.0' xmlns='http://schemas.microsoft.com/developer/msbuild/2003'> 
         <ItemGroup Label='Usings'> 
         <Reference Include='System' /> 
         <Reference Include='System.Xml' /> 
         </ItemGroup> 
        </Project>"; 

    XDocument doc = XDocument.Parse(xml2); 

    foreach (XElement element in doc.Descendants("ItemGroup")) 
    { 
     Console.WriteLine(element); 
    } 

स्ट्रिंग xml1 ठीक काम करता है, xml2 कुछ भी वापस नहीं करता है। उन स्ट्रिंग्स के बीच एकमात्र अंतर दस्तावेज़ रूट में xmlns विशेषता है।

मैं xmlns विशेषताओं वाले दस्तावेज़ों से कैसे क्वेरी करूं? यह एक समस्या क्यों है जब किसी XML दस्तावेज़ में xmlns विशेषता होती है?

उत्तर

16

यह एक समस्या क्यों है जब किसी XML दस्तावेज़ में xmlns विशेषता होती है?

यह नहीं है अगर आप समझते हैं कि यह क्या मतलब है :) मूल रूप से आप सभी तत्वों के लिए "http://schemas.microsoft.com/developer/msbuild/2003" का एक डिफ़ॉल्ट नाम स्थान यूआरआई लागू किया है। तो पूछताछ करते समय, आपको उस नामस्थान को भी निर्दिष्ट करने की आवश्यकता है। सौभाग्य से, LINQ से XML को वास्तव में सरल बनाता है:

XNamespace ns = "http://schemas.microsoft.com/developer/msbuild/2003"; 
XDocument doc = XDocument.Parse(xml2); 
foreach (XElement element in doc.Descendants(ns + "ItemGroup")) 
{ 
    Console.WriteLine(element); 
} 
+1

एक और वाक्यविन्यास: 'डॉक्टर। डिस्केन्डेंट्स ("{http://schemas.microsoft.com/developer/msbuild/2003}ItemGroup") ' – ziya

+1

क्षमा करें मुझे समझ में नहीं आता है कि हमें नामस्थान को स्पष्ट रूप से क्यों लिखना है इस दस्तावेज़ के लिए डिफॉल्ट है? यही कारण है कि XElement/XDocument द्वारा यह हल नहीं किया गया है? –

+0

@ फ़ेलिक्सकिइल: क्योंकि जब आप 'एलिमेंट' या 'descendants' कहते हैं तो आप 'XName' निर्दिष्ट कर रहे हैं, जो पूरी तरह से योग्य है ... और पूर्ण-योग्य नाम में नामस्थान शामिल है। मैं आपके बिंदु को देखता हूं, लेकिन मुझे लगता है कि यह समझ में आता है कि यह किस तरह से किया गया है, और LINQ से XML में नेमस्पेस समर्थन मैंने देखा है कि किसी भी XML एपीआई का सबसे अच्छा है। –

3

नामस्थान को पहले से जानना आवश्यक नहीं है। आप कोड लिख सकते हैं, जो दोनों एक्सएमएल के साथ काम करता है क्योंकि आप XElement से डिफ़ॉल्ट नेमस्पेस प्राप्त कर सकते हैं।

XDocument doc = XDocument.Parse(xml2); 
XNamespace ns = doc.Root.GetDefaultNamespace(); 
foreach (XElement element in doc.Descendants(ns + "ItemGroup")) 
{ 
    Console.WriteLine(element); 
} 

मैं भी किसी भी XObject (XElement, XDocument, आदि) से XName हल के लिए एक विस्तार विधि लिखा था।

GetDefaultNamespace के बजाय एक्सटेंशन विधि का उपयोग करने में लाभ यह है कि आपको यह जांचना नहीं है कि पहले से ही कोई अन्य नामस्थान प्रदान किया गया है या नहीं।

public static XName ResolveName(this XObject xObj, XName name) 
{ 
    //If no namespace has been added, use default namespace anyway 
    if (string.IsNullOrEmpty(name.NamespaceName)) 
    { 
     name = xObj.Document.Root.GetDefaultNamespace() + name.LocalName; 
    } 
    return name; 
} 

आप इस

XDocument doc = XDocument.Parse(xml2); 
foreach (XElement element in doc.Descendants(doc.ResolveName("ItemGroup"))) 
{ 
    Console.WriteLine(element); 
} 

मैं एक्सएमएल के लिए LINQ लगता है जैसे कि यह उपयोग कर सकते हैं एक अद्भुत एपीआई है। लेकिन मुझे लगता है कि यह स्पष्ट है, कि अगर मैं नामस्थान प्रदान नहीं करता हूं, तो मेरा हमेशा डिफ़ॉल्ट नामस्थान होता है। मुझे कोई कारण नहीं दिख रहा है कि LINQ से XML क्यों इस तरह से व्यवहार नहीं करता है। यह एक छोटी सी कमी है जो वास्तव में मुझे परेशान करती है। और पहली बार LINQ से एक्सएमएल के शुरुआती के रूप में मुझे पता नहीं था कि मैंने डिफ़ॉल्ट नामस्थान प्रदान करने के लिए घंटों के लिए क्या गलत किया था।

+0

ग्रेट, साझा करने के लिए धन्यवाद! – Joel

संबंधित मुद्दे