2010-12-02 14 views
11

जोड़ता है मैं एक नई एक्सएमएल फ़ाइल बनाने के लिए लिंक से एक्सएमएल का उपयोग कर रहा हूं। फ़ाइल का कुछ हिस्सा मुझे मौजूदा एक्सएमएल फाइल से मिलता है। मैं इसके लिए निम्नलिखित कोड का उपयोग करता हूं।XElement एक xmlns

var v2 = new XDocument(
    new XDeclaration("1.0", "utf-16", ""), 
    new XComment(string.Format("Converted from version 1. Date: {0}", DateTime.Now)), 
    new XElement(ns + "keyem", 
    new XAttribute(XNamespace.Xmlns + "xsd", xsd.NamespaceName), 
    new XAttribute(XNamespace.Xmlns + "xsi", xsi.NamespaceName), 
    new XAttribute(xsi + "schemaLocation", schemaLocation.NamespaceName), 
    new XAttribute("version", "2"), 
    new XAttribute("description", description), 
    new XElement(ns + "layout", 
     new XAttribute("type", type), 
     new XAttribute("height", height), 
     new XAttribute("width", width), 
     settings.Root)  // XML from an existing file 

समस्या यह है कि यह xmlns = मौजूदा फ़ाइल से पहले तत्व कहते हैं, "" है।

परिणाम है:

<?xml version="1.0" encoding="utf-16"?> 
<foo 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://tempuri.org/KeyEmFileSchema.xsd KeyEmFileSchema.xsd" 
    xmlns="http://tempuri.org/KeyEmFileSchema.xsd"> 
    <settings xmlns=""> 
     ... 
    </settings> 
</foo> 

एक्सएमएल फ़ाइल मैं इस तरह दिखता है से पढ़ रहा हूँ, लेकिन अगर

<?xml version="1.0" encoding="utf-16"?> 
<settings> 
    <colormaps> 
    <colormap color="Gray"  textcolor="Black"/> 
    <colormap color="DarkGray" textcolor="White"/> 
    <colormap color="Black" textcolor="White"/> 
    <colormap color="Cyan"  textcolor="Black"/> 
    </colormaps> 
    <macromaps> 
    <macromap pattern="^@([0-9A-F]{2})\|([0-9A-F]{2})$" replace="{ESC}$1{ESC}$2{MOUSERESET}"/> 
    <macromap pattern="^\$([0-9A-F]{2})\|([0-9A-F]{2})$" replace="{USERCLICK}{ESC}$1{ESC}$2{MOUSERESET}"/> 
    <macromap pattern="^\$([0-9A-F]{2})$"    replace="{USERCLICK}{ESC}$1"/> 
    </macromaps> 
    <keydefault color="Cyan"/> 
    <groupdefault color="DarkGray"/> 
</settings> 

उत्तर

11

आप इस को देख रहे हैं की जरूरत है मैं इसे बदल सकते हैं क्योंकि सेटिंग्स तत्व (संभवतः आपके दस्तावेज़ से आ रहा है) इस नामस्थान में नहीं रहता है। यह डिफ़ॉल्ट/शून्य-यूरी नेमस्पेस में रहता है।

आपको अपना नाम दस्तावेज़ बदलने के लिए अपने इनपुट दस्तावेज़ को बदलने की आवश्यकता होगी।

यह कुछ हद तक सरल उदाहरण, एक और दस्तावेज़ में अपने xml फ़ाइल और यह स्थानों ले लेकिन, इससे पहले कि यह ऐसा नहीं करता है यह अपने लक्ष्य दस्तावेज़ की है कि उस xml फ़ाइल में प्रत्येक तत्व का नाम स्थान परिवर्तन ...

static void ProcessXmlFile() 
    { 
     XNamespace ns = "http://tempuri.org/KeyEmFileSchema.xsd/"; 

     // load the xml document 
     XElement settings = XElement.Load("data.xml"); 

     // shift ALL elements in the settings document into the target namespace 
     foreach (XElement e in settings.DescendantsAndSelf()) 
     { 
      e.Name = ns + e.Name.LocalName; 
     } 

     // write the output document 
     var file = new XDocument(new XElement(ns + "foo", 
             settings)); 

     Console.Write(file.ToString());    
    } 

परिणाम है जो इस की ...

<foo xmlns="http://tempuri.org/KeyEmFileSchema.xsd/"> 
    <settings> 
    <colormaps> 
     <colormap color="Gray" textcolor="Black" /> 
     <colormap color="DarkGray" textcolor="White" /> 
     <colormap color="Black" textcolor="White" /> 
     <colormap color="Cyan" textcolor="Black" /> 
    </colormaps> 
    <macromaps> 
     <macromap pattern="^@([0-9A-F]{2})\|([0-9A-F]{2})$" replace="{ESC}$1{ESC}$2{MOUSERESET}" /> 
     <macromap pattern="^\$([0-9A-F]{2})\|([0-9A-F]{2})$" replace="{USERCLICK}{ESC}$1{ESC}$2{MOUSERESET}" /> 
     <macromap pattern="^\$([0-9A-F]{2})$" replace="{USERCLICK}{ESC}$1" /> 
    </macromaps> 
    <keydefault color="Cyan" /> 
    <groupdefault color="DarkGray" /> 
    </settings> 
</foo> 

आप देख सकते हैं, सेटिंग्स तत्व अब foo तत्व के रूप में एक ही नाम स्थान में है। यह अनिवार्य रूप से एक त्वरित और गंदे एक्सएमएल परिवर्तन है, और स्पष्ट रूप से यह आपके द्वारा आयात किए जा रहे एक्सएमएल दस्तावेज़ में किसी भी नामस्थान का सम्मान नहीं करता है। लेकिन यह हो सकता है कि आप बाद में हो, या कम से कम कुछ और मजबूत आधार का आधार बना सकते हैं।

+0

मैं समझता हूं, लेकिन मैं यह कैसे कर सकता हूं? मैंने डिफ़ॉल्ट सेटिंग्स की कोशिश की है। नाम = ns + defaultSettings.Name.LocalName; लेकिन मुझे इसे सभी उप-तत्वों के लिए करना होगा। कुछ बेहतर होना चाहिए। – magol

+0

आपको या तो Xslt तकनीकों का उपयोग करके दस्तावेज़ को बदलने की आवश्यकता है, या प्रत्येक तत्व को पढ़ने और कोड में बदलने के लिए। असल में, आपके द्वारा लोड किया गया एक्स डॉक्यूमेंट उस दस्तावेज़ में प्रत्येक तत्व के नामस्थान को जानता है, और पता है कि यह foo के समान नामस्थान नहीं है। –

+0

क्या मैं उस एक्सएमएल फ़ाइल को बदल सकता हूं जिसे मैंने सही नामस्थान में प्राप्त करने के लिए पढ़ा है? – magol

1

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

public static XElement EnsureNamespaceExists(this XElement xElement, XNamespace xNamespace) 
{ 
    string nodeName = xElement.Name.LocalName; 

    if (!xElement.HasAttribute("xmlns")) 
    { 
     foreach (XElement tmpElement in xElement.DescendantsAndSelf()) 
     { 
      tmpElement.Name = xNamespace + tmpElement.Name.LocalName; 
     } 
     xElement = new XElement(xNamespace + nodeName, xElement.FirstNode); 
    } 

    return xElement; 
}