.net - सबसे अच्छा तरीका है एक XElement की इनरएक्सएलएमएल प्राप्त करने के लिए?




xml innerxml (10)

नीचे दिए गए कोड में मिश्रित body तत्व की सामग्री प्राप्त करने का सबसे अच्छा तरीका क्या है? तत्व में एक्सएचटीएमएल या पाठ हो सकता है, लेकिन मैं सिर्फ इसकी सामग्री को स्ट्रिंग रूप में चाहता हूं। XmlElement टाइप में InnerXml प्रॉपर्टी होती है जो कि वास्तव में मेरे बाद है।

जैसा कि लिखा गया कोड लगभग वही करता है जो मैं चाहता हूं, लेकिन इसमें आसपास <body> ... </body> तत्व शामिल है, जो मुझे नहीं चाहिए।

XDocument doc = XDocument.Load(new StreamReader(s));
var templates = from t in doc.Descendants("template")
                where t.Attribute("name").Value == templateName
                select new
                {
                   Subject = t.Element("subject").Value,
                   Body = t.Element("body").ToString()
                };

// रेगेक्स का उपयोग करना शुरू और अंत तत्व टैग को ट्रिम करने के लिए तेज हो सकता है

var content = element.ToString();
var matchBegin = Regex.Match(content, @"<.+?>");
content = content.Substring(matchBegin.Index + matchBegin.Length);          
var matchEnd = Regex.Match(content, @"</.+?>", RegexOptions.RightToLeft);
content = content.Substring(0, matchEnd.Index);

@Greg: ऐसा प्रतीत होता है कि आपने अपने उत्तर को पूरी तरह से अलग उत्तर के रूप में संपादित किया है। जिस पर मेरा उत्तर हाँ है, मैं System.Xml का उपयोग करके ऐसा कर सकता था, लेकिन LINQ से XML तक मेरे पैर गीले होने की आशा कर रहा था।

मैं अपना मूल उत्तर नीचे छोड़ दूंगा यदि कोई और आश्चर्य करता है कि मैं XElement की .Value संपत्ति का उपयोग क्यों नहीं कर सकता, ताकि मैं इसे प्राप्त कर सकूं:

@Greg: मान गुण किसी भी बच्चे के नोड्स की सभी पाठ्य सामग्री को समाप्‍त कर देता है। इसलिए अगर बॉडी एलिमेंट में केवल टेक्स्ट ही काम करता है, लेकिन अगर इसमें एक्सएचटीएमएल है तो मुझे सभी टेक्स्ट एक साथ मिल जाते हैं लेकिन कोई भी टैग नहीं।



आश्चर्य है कि अगर (मुझे b + = से छुटकारा मिल गया है और अभी b + है)

t.Element( "body" ).Nodes()
 .Aggregate( "", ( b, node ) => b + node.ToString() );

की तुलना में थोड़ा कम कुशल हो सकता है

string.Join( "", t.Element.Nodes()
                  .Select( n => n.ToString() ).ToArray() );

100% निश्चित नहीं ... लेकिन रिफ्लेक्टर में एग्रीगेट () और स्ट्रिंग.जॉइन () पर नज़र ... मुझे लगता है कि मैं इसे एग्रीगेट के रूप में पढ़ता हूं, केवल एक रिटर्निंग वैल्यू को जोड़ रहा हूं, इसलिए अनिवार्य रूप से आपको मिलता है:

string = string + स्ट्रिंग

बनाम string.Join, इसमें FastStringAllocation या कुछ और के बारे में कुछ उल्लेख किया गया है, जिससे मुझे लगता है कि लोगों ने Microsoft पर कुछ अतिरिक्त प्रदर्शन को बढ़ावा दिया है। बेशक मेरे .ToArray () मेरे नकारात्मक फोन है कि, लेकिन मैं सिर्फ एक और सुझाव देना चाहता था।


उन लोगों के लिए सभी उचित श्रेय के साथ जिन्होंने सर्वोत्तम दृष्टिकोण की खोज की और साबित किया (धन्यवाद!), यहां इसे विस्तार पद्धति में लपेटा गया है:

public static string InnerXml(this XNode node) {
    using (var reader = node.CreateReader()) {
        reader.MoveToContent();
        return reader.ReadInnerXml();
    }
}

क्या LINQ का उपयोग करने के बजाय यहां काम करने के लिए System.Xml नामस्थान वस्तुओं का उपयोग करना संभव है? जैसा कि आपने पहले ही उल्लेख किया है, XmlNode.InnerXml वही है जिसकी आपको आवश्यकता है।


निजी तौर पर, मैंने एग्रीगेट विधि का उपयोग करके एक InnerXml एक्सटेंशन विधि लिखना समाप्त किया:

public static string InnerXml(this XElement thiz)
{
   return thiz.Nodes().Aggregate( string.Empty, ( element, node ) => element += node.ToString() );
}

मेरा क्लाइंट कोड तो उसी तरह है जैसे कि यह पुराने System.Xml नाम स्थान के साथ होगा।

var innerXml = myXElement.InnerXml();

मुझे लगता है कि यह एक बेहतर तरीका है (VB में, अनुवाद करने के लिए कठिन नहीं होना चाहिए):

XElement x को देखते हुए:

Dim xReader = x.CreateReader
xReader.MoveToContent
xReader.ReadInnerXml

मैंने इसका उपयोग करते हुए समाप्त किया:

Body = t.Element("body").Nodes().Aggregate("", (b, node) => b += node.ToString());

public static string InnerXml(this XElement xElement)
{
    //remove start tag
    string innerXml = xElement.ToString().Trim().Replace(string.Format("<{0}>", xElement.Name), "");
    ////remove end tag
    innerXml = innerXml.Trim().Replace(string.Format("</{0}>", xElement.Name), "");
    return innerXml.Trim();
}





innerxml