2009-01-25 4 views
8

मैं एक्सएचटीएमएल दस्तावेज़ बनाने के लिए System.Xml.Linq का उपयोग करने का प्रयास कर रहा हूं।XNlement को सभी बच्चों के नोड्स में XNamespace का उपयोग किए बिना डिफ़ॉल्ट नामस्थान के साथ XElement कैसे बनाएं

http://www.w3.org/1999/xhtml 

मैं बना सकते हैं XElement नोड्स आसानी से पर्याप्त इस नाम स्थान के दायरे वाला, एक XNamespace उपयोग करते हुए, इस तरह::

XNamespace xhtml = "http://www.w3.org/1999/xhtml"; 
// ... 
new XElement(xhtml + "html", // ... 

इस प्रकार, मेरी पेड़ में नोड्स के विशाल बहुमत इस नाम स्थान का उपयोग करना चाहिए हालांकि, मैं HTML कोड नोड्स बनाने वाले सभी कोडों में XNamespace उपलब्ध नहीं करना चाहता हूं, और मुझे प्रत्येक XElement (और XAttribute) नाम उपसर्ग करना होगा, जैसा कि मैं तदनुसार बनाता हूं।

एक्सएमएल टेक्स्ट प्रारूप स्वयं ही इस आवश्यकता को ध्यान में रखता है, और आरक्षित xmlns विशेषता का उपयोग करके वंशजों द्वारा विरासत में प्राप्त एक पूर्वजों में एक डिफ़ॉल्ट नामस्थान सेट करने की अनुमति देता है। मैं System.Xml.Linq का उपयोग कर कुछ ऐसा करना चाहता हूं।

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

उत्तर

5

मैं एक स्थिर वर्ग, XHtml कहा जाता है कि इस तरह दिखता है उपयोग करने के लिए तय कर लिया है:

public static class XHtml 
{ 
    static XHtml() 
    { 
     Namespace = "http://www.w3.org/1999/xhtml"; 
    } 

    public static XNamespace Namespace { get; private set; } 

    public static XElement Element(string name) 
    { 
     return new XElement(Namespace + name); 
    } 

    public static XElement Element(string name, params object[] content) 
    { 
     return new XElement(Namespace + name, content); 
    } 

    public static XElement Element(string name, object content) 
    { 
     return new XElement(Namespace + name, content); 
    } 

    public static XAttribute Attribute(string name, object value) 
    { 
     return new XAttribute(/* Namespace + */ name, value); 
    } 

    public static XText Text(string text) 
    { 
     return new XText(text); 
    } 

    public static XElement A(string url, params object[] content) 
    { 
     XElement result = Element("a", content); 
     result.Add(Attribute("href", url)); 
     return result; 
    } 
} 

इस का स्पष्ट तरीका प्रतीत हो रहा है चीजें करना, विशेष रूप से जब मैं सुविधाजनक दिनचर्या में जोड़ सकता हूं, जैसे कि XHtml.A विधि (मेरी सभी कक्षा यहां दिखाई नहीं दे रही है)।

+0

यह समाधान भारी और डरावना दिखता है, लेकिन यह वास्तव में अच्छा, हल्का, एक्स्टेंसिबल है, आपके कोड को छोटा बनाता है और तत्व या विशेषता नामों में टाइपो के खिलाफ सुरक्षा करता है। वाह! –

+0

मुझे बस समझ में आया कि इन सभी फायदे क्यों हैं। हालांकि सवाल केवल "मैं स्वचालित नामस्थान चाहता हूं", सरल और सौहार्दपूर्ण बात यह है कि "मुझे कुछ सुविधा शॉर्टकट चाहिए जो HTML के कुछ बुनियादी ज्ञान को समाहित करते हैं", जिनमें से नामस्थान प्रभाव केवल एक अच्छा उप-उत्पाद है। –

1

समस्या यह है कि XName को सही नामस्थान निर्दिष्ट करने के लिए XElement आवश्यकताएं बनाने के लिए उपयोग किया जाता है।

public static class XHtml 
{ 
    public static readonly XNamespace Namespace = "http://www.w3.org/1999/xhtml"; 
    public static XName Html { get { return Namespace + "html"; } } 
    public static XName Body { get { return Namespace + "body"; } } 
       //.. other element types 
} 

अब आप इस तरह की एक एक्सएचटीएमएल दस्तावेज़ निर्माण कर सकते हैं: - -:

XDocument doc = new XDocument(
    new XElement(XHtml.Html, 
     new XElement(XHtml.Body) 
    ) 
); 

कि स्थिर वर्ग के लिए एक वैकल्पिक दृष्टिकोण होगा मैं क्या करने के लिए परीक्षा की जाएगी इस तरह एक स्थिर वर्ग बनाने है : -

static class XHtml 
{ 
    public static readonly XNamespace Namespace = "http://www.w3.org/1999/xhtml"; 
    public static readonly XName Html = Namespace + "html"; 
    public static readonly XName Body = Namespace + "body"; 
} 

यह है कि क्या आप उन्हें इस्तेमाल की परवाह किए बिना सभी संभव XName instancing का नकारात्मक पहलू है, लेकिन उल्टा नाम स्थान + "टैगनाम" का रूपांतरण है केवल एक बार होता। मुझे यकीन नहीं है कि यह रूपांतरण अन्यथा अनुकूलित किया जाएगा। मुझे यकीन है कि XNames केवल instanced एक बार कर रहे हैं रहा हूँ: -

XNamepace n = "http://www.w3.org/1999/xhtml"; 
XNames x = n + "A"; 
XName y = n + "A"; 
Object.ReferenceEquals(x, y) //is true. 
+0

रूट पर XDocument में जोड़ने से पहले, एक तीसरा दृष्टिकोण उपट्री, एचटीएमएल-नोड डाउन को फिर से लिखना है। मैं समस्या को हल करने के इन अन्य तरीकों से अवगत हूं, मैं सोच रहा था कि इसके आसपास कोई रास्ता है या नहीं। मुझे लगता है शायद नहीं। –

+0

उम्म ... हुह? एचटीएमएल-नोड नीचे? मुझे वह नहीं मिला। आपको अभी भी XNames का उपयोग करने की आवश्यकता होगी जिसमें xhtml नेमस्पेस हो। – AnthonyWJones

+0

एंथनी - नामों में एक्सएचटीएमएल नेमस्पेस को शामिल करने के लिए पेड़ को फिर से लिखना, जिन्हें नामस्थान द्वारा स्कॉप्ड नहीं किया गया है, यानी XName.Namespace XNamespace.None है; एचटीएमएल नोड द्वारा, मेरा मतलब एक्सएचटीएमएल दस्तावेजों का रूट नोड है। –

3

मैंने पुनरावर्ती पुनर्लेखन पथ लिया। आपको पेड़ को 'पुनर्निर्माण' करने की ज़रूरत नहीं है। आप नोड नामों को केवल स्वैप कर सकते हैं (XName)।

private static void ApplyNamespace(XElement parent, XNamespace nameSpace) 
    { 
     if(DetermineIfNameSpaceShouldBeApplied(parent, nameSpace)) 
     { 
      parent.Name = nameSpace + parent.Name.LocalName; 
     } 
     foreach (XElement child in parent.Elements()) 
     { 
      ApplyNamespace(child, nameSpace); 
     } 
    } 
संबंधित मुद्दे