2013-08-12 7 views
15

मेरे पास कोई रूट फ़ाइल नहीं है। मैं इसे बदल नहीं सकता मैं इसे पार्स करने की कोशिश कर रहा हूं, लेकिन XDocument.Load ऐसा नहीं करेगा। मैंने ConformanceLevel.Fragment सेट करने का प्रयास किया है, लेकिन मुझे अभी भी एक अपवाद फेंक दिया गया है। क्या किसी के पास इसका कोई समाधान है?सी # एक्सडॉक्यूमेंट लोड कई जड़ें

मैंने XmlReader के साथ प्रयास किया, लेकिन चीजें गड़बड़ हो गईं और इसे सही काम नहीं मिल सका। XDocument.Load बहुत अच्छा काम करता है, लेकिन अगर मेरे पास एकाधिक जड़ों वाली फाइल है, तो यह नहीं है।

+1

'XDocument.Load' काम नहीं करता है, क्योंकि उस तरह की फ़ाइल वैध XML दस्तावेज़ नहीं है। – MarcinJuraszek

+0

क्या आप वह कोड पोस्ट कर सकते हैं जिसे आपने अभी तक आजमाया है? – christiandev

+0

अलग-अलग प्रश्न, एक ही उत्तर: http://stackoverflow.com/a/9378442 – dtb

उत्तर

14

XmlReader ही xml टुकड़ा के समर्थन पढ़ने करता है - जो कि

var settings = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment }; 
using (var reader = XmlReader.Create("fragment.xml", settings)) 
{ 
    // you can work with reader just fine 
} 

हालांकि XDocument.Load खंडित एक्सएमएल के पढ़ने का समर्थन नहीं करता।

XDocument.Parse का आह्वान करने से पहले त्वरित और गंदा तरीका एक आभासी रूट के नीचे नोड्स को लपेटना है। पसंद:

var fragments = File.ReadAllText("fragment.xml"); 
var myRootedXml = "<root>" + fragments + "</root>"; 
var doc = XDocument.Parse(myRootedXml); 

यह दृष्टिकोण छोटी xml फ़ाइलों तक सीमित है - क्योंकि आपको पहले स्मृति में फ़ाइल को पढ़ना है; और बड़ी स्ट्रिंग को संयोजित करने का मतलब है स्मृति में बड़ी वस्तुओं को स्थानांतरित करना - जो सबसे अच्छा बचा है।

यदि प्रदर्शन मामलों आप XmlReader @ मार्टिन-Honnen के जवाब (https://stackoverflow.com/a/18203952/2440262)

उत्कृष्ट में के रूप में समझाया आप एपीआई कि दी कि XmlReader दोहराता के लिए ले जाता है का उपयोग करते हैं के माध्यम से XDocument एक-एक करके में नोड्स पढ़ने जाना चाहिए वैध एक्सएमएल, और प्रदर्शन मामलों पर, आप के बजाय शामिल हो गए धारा दृष्टिकोण का उपयोग कर सकते हैं:

using (var jointStream = new MultiStream()) 
using (var openTagStream = new MemoryStream(Encoding.ASCII.GetBytes("<root>"), false)) 
using (var fileStream = 
    File.Open(@"fragment.xml", FileMode.Open, FileAccess.Read, FileShare.Read)) 
using (var closeTagStream = new MemoryStream(Encoding.ASCII.GetBytes("</root>"), false)) 
{ 
    jointStream.AddStream(openTagStream); 
    jointStream.AddStream(fileStream); 
    jointStream.AddStream(closeTagStream); 
    using (var reader = XmlReader.Create(jointStream)) 
    { 
     // now you can work with reader as if it is reading valid xml 
    } 
} 

MultiStream - उदाहरण के लिए देखें https://gist.github.com/svejdo1/b9165192d313ed0129a679c927379685

नोट: XDocument पूरे एक्सएमएल को स्मृति में लोड करता है। तो इसे बड़ी फ़ाइलों के लिए उपयोग न करें - इसके बजाय XmlReader को पुनरावृत्ति के लिए उपयोग करें और XElementXNode.ReadFrom(...)

+6

'XDocument.Parse()' का उपयोग करके 'स्ट्रिंग रीडर' में स्ट्रिंग को लपेटने की आवश्यकता को खत्म करना चाहिए। – CoderDennis

0

XML दस्तावेज़ में एक से अधिक रूट तत्व नहीं हो सकते हैं। एक मूल तत्व की आवश्यकता है। आप एक काम कर सकते हैं। सभी fragment तत्व प्राप्त करें और उन्हें मूल तत्व में लपेटें और इसे XDocument के साथ पार्स करें।

यह सबसे अच्छा और आसान तरीका होगा जो कोई सोच सकता है।

1

यदि आप XmlDocument.Load() का उपयोग करना चाहते हैं तो आपको सामग्री को रूट नोड में लपेटना होगा।

या आप कुछ इस तरह की कोशिश कर सकते ...

while (xmlReader.Read()) 
{ 
    if (xmlReader.NodeType == XmlNodeType.Element) 
    { 
     XmlDocument d = new XmlDocument(); 
     d.CreateElement().InnerText = xmlReader.ReadOuterXml(); 
    } 
} 
12
नेट रूपरेखा है कि टुकड़े के साथ सौदा कर सकते हैं में

केवल इन-स्मृति पेड़ अभ्यावेदन नेट के डोम कार्यान्वयन में तो आप की आवश्यकता होगी XmlDocumentFragment हैं XmlDocument और उदाहरण के साथ एक खंड बनाने के लिए

XPathDocument doc; 
using (XmlReader xr = 
       XmlReader.Create("fragment.xml", 
            new XmlReaderSettings() 
            { 
             ConformanceLevel = ConformanceLevel.Fragment 
            })) 
{ 
    doc = new XPathDocument(xr); 
} 

// new create XPathNavigator for read out data e.g. 
XPathNavigator nav = doc.CreateNavigator(); 

केवल पढ़ने के लिए जाहिर है XPathNavigator है:

XmlDocument doc = new XmlDocument(); 
XmlDocumentFragment frag = doc.CreateDocumentFragment(); 
frag.InnerXml = stringWithXml; // for instance 
           // frag.InnerXml = File.ReadAllText("fragment.xml"); 

या है XPathDocument जहां ConformanceLevel के साथ एक XmlReader का उपयोग कर बना सकते हैं टुकड़ा करने के लिए निर्धारित किया है।

यदि आप LINQ से XML का उपयोग करना चाहते हैं तो मैं सुझावों से सहमत हूं कि आपको एक रैपर के रूप में XElement बनाने की आवश्यकता है। फ़ाइल सामग्री के साथ एक स्ट्रिंग में खींचने के बजाय आप XNode.ReadFrom का उपयोग XmlReader के साथ कर सकते हैं उदा।

public static class MyExtensions 
{ 
    public static IEnumerable<XNode> ParseFragment(XmlReader xr) 
    { 
     xr.MoveToContent(); 
     XNode node; 
     while (!xr.EOF && (node = XNode.ReadFrom(xr)) != null) 
     { 
      yield return node; 
     } 
    } 
} 

तो

XElement root = new XElement("root", 
          MyExtensions.ParseFragment(XmlReader.Create(
           "fragment.xml", 
           new XmlReaderSettings() { 
           ConformanceLevel = ConformanceLevel.Fragment }))); 

बेहतर और अधिक एक स्ट्रिंग में सब कुछ पढ़ने की तुलना में कुशलता से काम कर सकते हैं यही कारण है कि।

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