C # में XML से कैसे निपटें


85

C # 2.0 में XML दस्तावेज़, XSD आदि से निपटने का सबसे अच्छा तरीका क्या है?

कौन सी कक्षाओं का उपयोग करना है आदि XML दस्तावेज़ों को पार्स करने और बनाने की सर्वोत्तम प्रथाएँ क्या हैं?

EDIT: .net 3.5 सुझावों का भी स्वागत है।


उन लोगों के लिए जो अधिक व्यावहारिक समाधान खोजने की कोशिश कर रहे हैं, इस पर ध्यान न दें। यह एक .NET पुस्तकालय पुराना है। इसके बजाय XDocument का उपयोग करें, और आप हताशा में अपनी आँखों को बाहर निकालने से बचेंगे
AER

जवाबों:


177

C # 2.0 में पढ़ने और लिखने का प्राथमिक साधन XmlDocument वर्ग के माध्यम से किया जाता है । आप अपनी अधिकांश सेटिंग को सीधे XmlDocument में XmlReader के माध्यम से लोड कर सकते हैं।

XML को सीधे लोड कर रहा है

XmlDocument document = new XmlDocument();
document.LoadXml("<People><Person Name='Nick' /><Person Name='Joe' /></People>");

फ़ाइल से XML लोड हो रहा है

XmlDocument document = new XmlDocument();
document.Load(@"C:\Path\To\xmldoc.xml");
// Or using an XmlReader/XmlTextReader
XmlReader reader = XmlReader.Create(@"C:\Path\To\xmldoc.xml");
document.Load(reader);

मुझे XPath का उपयोग करके XML दस्तावेज़ पढ़ने का सबसे आसान / सबसे तेज़ तरीका लगता है।

XPath (XmlDocument का उपयोग करके एक XML दस्तावेज़ पढ़ना) जो हमें संपादित करने की अनुमति देता है)

XmlDocument document = new XmlDocument();
document.LoadXml("<People><Person Name='Nick' /><Person Name='Joe' /></People>");

// Select a single node
XmlNode node = document.SelectSingleNode("/People/Person[@Name = 'Nick']");

// Select a list of nodes
XmlNodeList nodes = document.SelectNodes("/People/Person");

यदि आपको XML दस्तावेज़ को मान्य करने के लिए XSD दस्तावेज़ों के साथ काम करने की आवश्यकता है तो आप इसका उपयोग कर सकते हैं।

XSD स्कीमों के खिलाफ XML दस्तावेजों को मान्य करना

XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidateType = ValidationType.Schema;
settings.Schemas.Add("", pathToXsd); // targetNamespace, pathToXsd

XmlReader reader = XmlReader.Create(pathToXml, settings);
XmlDocument document = new XmlDocument();

try {
    document.Load(reader);
} catch (XmlSchemaValidationException ex) { Trace.WriteLine(ex.Message); }

प्रत्येक नोड पर XSD के खिलाफ XML का सत्यापन (अद्यतन 1)

XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidateType = ValidationType.Schema;
settings.Schemas.Add("", pathToXsd); // targetNamespace, pathToXsd
settings.ValidationEventHandler += new ValidationEventHandler(settings_ValidationEventHandler);

XmlReader reader = XmlReader.Create(pathToXml, settings);
while (reader.Read()) { }

private void settings_ValidationEventHandler(object sender, ValidationEventArgs args)
{
    // e.Message, e.Severity (warning, error), e.Error
    // or you can access the reader if you have access to it
    // reader.LineNumber, reader.LinePosition.. etc
}

XML दस्तावेज़ लिखना (मैन्युअल रूप से)

XmlWriter writer = XmlWriter.Create(pathToOutput);
writer.WriteStartDocument();
writer.WriteStartElement("People");

writer.WriteStartElement("Person");
writer.WriteAttributeString("Name", "Nick");
writer.WriteEndElement();

writer.WriteStartElement("Person");
writer.WriteStartAttribute("Name");
writer.WriteValue("Nick");
writer.WriteEndAttribute();
writer.WriteEndElement();

writer.WriteEndElement();
writer.WriteEndDocument();

writer.Flush();

(अद्यतन 1)

.NET 3.5 में, आप समान कार्य करने के लिए XDocument का उपयोग करते हैं। हालांकि, अंतर यह है कि आपको आवश्यक डेटा का चयन करने के लिए Linq Queries के प्रदर्शन का लाभ है। ऑब्जेक्ट इनिशियलाइज़र के जुड़ने से आप एक क्वेरी बना सकते हैं, जो क्वेरी में ही आपकी अपनी परिभाषा की वस्तुओं को भी लौटाती है।

    XDocument doc = XDocument.Load(pathToXml);
    List<Person> people = (from xnode in doc.Element("People").Elements("Person")
                       select new Person
                       {
                           Name = xnode.Attribute("Name").Value
                       }).ToList();

(अद्यतन 2)

.NET 3.5 में एक अच्छा तरीका यह है कि XML बनाने के लिए XDocument का उपयोग किया जाए। यह कोड वांछित आउटपुट के समान पैटर्न में दिखाई देता है।

XDocument doc =
        new XDocument(
              new XDeclaration("1.0", Encoding.UTF8.HeaderName, String.Empty),
              new XComment("Xml Document"),
              new XElement("catalog",
                    new XElement("book", new XAttribute("id", "bk001"),
                          new XElement("title", "Book Title")
                    )
              )
        );

बनाता है

<!--Xml Document-->
<catalog>
  <book id="bk001">
    <title>Book Title</title>
  </book>
</catalog>

बाकी सब विफल रहता है, आप इस MSDN लेख की जांच कर सकते हैं जिसमें कई उदाहरण हैं जिनकी मैंने यहां चर्चा की है और बहुत कुछ। http://msdn.microsoft.com/en-us/library/aa468556.aspx


3
आप यह बताना चाह सकते हैं कि आप XDocument का अंतिम उदाहरण में XDocument का उपयोग कर रहे हैं क्योंकि XmlDocument से काफी भिन्न है
एरॉन पॉवेल

2
भूल सुधार; कोई C # 3.5 नहीं है; आप मतलब .NET 3.5 और सी # 3.0
मार्क Gravell

ओह, और "मक्खी पर" [वस्तु initializers] मोटे तौर पर ही सी # 3.0 और XmlDocument के साथ काम करेगा - अभी भी एक अच्छा जवाब है, हालांकि (+1)
मार्क Gravell

यह ध्यान देने योग्य हो सकता है कि यदि आप XPath के साथ क्वेरी करने के लिए एक दस्तावेज़ लोड कर रहे हैं (और संपादित नहीं करते हैं) तो एक XPathDocument का उपयोग करना बहुत अधिक कुशल होगा
ओलिवर हॉलम

क्या यह स्कीम वैलिडेशन नोड द्वारा नोड किया गया है? यदि नहीं, तो क्या नोड द्वारा इसे नोड करने का एक तरीका है?
मलिक दाउद अहमद खोखर

30

यह आकार पर निर्भर करता है; छोटे से मध्य आकार के xml के लिए, एक DOM जैसे XmlDocument (कोई C # /। NET संस्करण) या XDocument (.NET 3.5 / C # 3.0) स्पष्ट विजेता है। XSD का उपयोग कर के लिए, आप एक्सएमएल एक का उपयोग कर लोड कर सकते हैं XmlReader , और एक XmlReader (करने के लिए स्वीकार करता बनाएं ) एक XmlReaderSettings । XmlReaderSettings ऑब्जेक्ट में एक स्कीमा गुण है जिसका उपयोग xsd (या dtd) सत्यापन करने के लिए किया जा सकता है।

Xml लिखने के लिए, वही चीजें लागू होती हैं, यह देखते हुए कि पुराने XmlDocument की तुलना में LINQ-to-XML (XDocument) के साथ सामग्री रखना थोड़ा आसान है।

हालाँकि, विशाल xml के लिए, एक DOM बहुत अधिक मेमोरी को धूमिल कर सकता है, इस स्थिति में आपको सीधे XmlReader / XmlWriter का उपयोग करने की आवश्यकता हो सकती है।

अंत में, xml में हेरफेर के लिए आप XslCompiledTransform (एक xslt लेयर) का उपयोग करना चाह सकते हैं ।

Xml के साथ काम करने का विकल्प ऑब्जेक्ट मॉडल के साथ काम करना है; आप xsd.exe का उपयोग उन कक्षाओं को बनाने के लिए कर सकते हैं जो एक xsd-compliant मॉडल का प्रतिनिधित्व करते हैं, और बस xml को ऑब्जेक्ट के रूप में लोड करते हैं , इसे OO के साथ जोड़तोड़ करते हैं, और फिर उन वस्तुओं को फिर से अनुक्रमित करते हैं; आप XmlSerializer के साथ ऐसा करते हैं


एक बड़े XML दस्तावेज़ (40k लाइन्स) में हेरफेर करने (तत्वों को जोड़ने / दबाने) के लिए। सबसे अच्छा तरीका क्या है? मैं LINQ-to-XML का उपयोग करता था।
नेह

12

nyxtom का जवाब बहुत अच्छा है। मैं इसमें कुछ चीजें जोड़ूंगा:

अगर आपको किसी XML डॉक्यूमेंट को रीड-ओनली एक्सेस की आवश्यकता होती है, XPathDocumentतो तुलना में बहुत हल्का-वज़न ऑब्जेक्ट है XmlDocument

उपयोग करने XPathDocumentका नकारात्मक पक्ष यह है कि आप परिचित SelectNodesऔर SelectSingleNodeतरीकों का उपयोग नहीं कर सकते हैं XmlNode। इसके बजाय, आपको उन उपकरणों का उपयोग करना होगा जो IXPathNavigableप्रदान करता है: a CreateNavigatorबनाने के लिए उपयोग करें XPathNavigator, और XPath के माध्यम से मिलने वाले नोड्स की सूचियों पर पुनरावृति XPathNavigatorकरने के लिए XPathNodeIterators बनाने के लिए उपयोग करें । यह आमतौर पर XmlDocumentतरीकों की तुलना में कोड की कुछ और लाइनों की आवश्यकता होती है ।

लेकिन: XmlDocumentऔर XmlNodeकक्षाएं लागू होती हैं IXPathNavigable, इसलिए आप जिस किसी भी कोड को एक XPathDocumentइच्छा पर उन तरीकों का उपयोग करने के लिए लिखते हैं वह भी एक पर काम करेगा XmlDocument। यदि आप के खिलाफ लिखने की आदत है IXPathNavigable, तो आपके तरीके किसी भी वस्तु के खिलाफ काम कर सकते हैं। (यही कारण है कि प्रयोग XmlNodeऔर XmlDocumentविधि में हस्ताक्षर FxCop द्वारा चिह्नित किए गए हैं।)

शायद ही, XDocumentऔर XElement( XNodeऔर XObject) लागू नहीं होते हैं IXPathNavigable

Nyxtom के जवाब में एक और बात मौजूद नहीं है XmlReader। आप आमतौर पर XmlReaderएक्सएमएल स्ट्रीम को ऑब्जेक्ट मॉडल में पार्स करने के ओवरहेड से बचने के लिए उपयोग करते हैं इससे पहले कि आप इसे संसाधित करना शुरू करें। इसके बजाय, आप XmlReaderएक बार में इनपुट स्ट्रीम एक एक्सएमएल नोड को संसाधित करने के लिए उपयोग करते हैं । यह अनिवार्य रूप से SAX के लिए .NET का उत्तर है। यह आपको बहुत बड़े XML दस्तावेज़ों को संसाधित करने के लिए बहुत तेज़ कोड लिखने देता है।

XmlReader XML दस्तावेज़ अंशों को संसाधित करने का सबसे सरल तरीका भी प्रदान करता है, उदाहरण के लिए XML तत्वों की धारा जिसमें कोई एन्क्लूडिंग तत्व नहीं है जो SQL सर्वर का XML RAW विकल्प देता है।

आपके द्वारा उपयोग किया जाने वाला कोड XmlReaderआमतौर पर बहुत ही कसकर युग्मित होता है XML के प्रारूप में जो इसे पढ़ रहा है। XPath का उपयोग करने से आपका कोड बहुत अधिक हो जाता है, बहुत अधिक शिथिल रूप से XML को युग्मित किया जाता है, यही कारण है कि यह आम तौर पर सही उत्तर है। लेकिन जब आपको उपयोग करने की आवश्यकता होती है XmlReader, तो आपको वास्तव में इसकी आवश्यकता होती है।


3
ध्यान दें कि (जिसमें व्युत्पन्न वर्ग भी शामिल है ) से XPathNavigator CreateNavigator(this XNode node)बनाने के लिए एक विस्तार विधि है । XPathNavigatorXNodeXDocument
डेव

5

सबसे पहले, नए XDocument और XElement वर्गों को जानें , क्योंकि वे पिछले XmlDocument परिवार पर एक सुधार हैं।

  1. वे LINQ के साथ काम करते हैं
  2. वे तेज और अधिक हल्के होते हैं

हालाँकि , आपको अभी भी पुराने वर्गों का उपयोग विरासत कोड के साथ काम करने के लिए करना पड़ सकता है - विशेष रूप से पहले से उत्पन्न परदे के पीछे। उस स्थिति में, आपको इन XML- हैंडलिंग कक्षाओं के बीच अंतर करने के लिए कुछ पैटर्न से परिचित होने की आवश्यकता होगी।

मुझे लगता है कि आपका प्रश्न काफी व्यापक है, और विवरण देने के लिए एक उत्तर में बहुत अधिक आवश्यकता होगी, लेकिन यह पहला सामान्य उत्तर है जिसके बारे में मैंने सोचा था, और एक शुरुआत के रूप में कार्य करता है।


मैं मानता हूं कि वे (XDocument आदि) महान हैं, लेकिन ओपी ने C # 2.0 के बारे में पूछा।
मार्क Gravell


2

यदि आप .NET 3.5 में काम कर रहे हैं और आप प्रायोगिक कोड से भयभीत नहीं हैं तो आप LINQ से XSD ( http://blogs.msdn.com/xmlteam/archive/2008/02/21/linq-to- देखें) xsd- अल्फा-0-2.aspx ) जो एक XSD से .NET क्लास उत्पन्न करेगा (जिसमें XSD से नियमों में बनाया गया है)।

फिर इसमें एक फ़ाइल से सीधे लिखने की क्षमता है और यह सुनिश्चित करने वाली फ़ाइल से पढ़ी जाती है कि यह XSD नियमों के अनुरूप है।

मैं निश्चित रूप से आपके द्वारा काम करने वाले किसी भी XML दस्तावेज़ के लिए XSD होने का सुझाव देता हूं:

  • आपको XML में नियम लागू करने की अनुमति देता है
  • दूसरों को यह देखने की अनुमति देता है कि XML कैसे संरचित है / होगी
  • XML के सत्यापन के लिए इस्तेमाल किया जा सकता है

मुझे लगता है कि लिक्विड एक्सएमएल स्टूडियो एक्सएसडी उत्पन्न करने के लिए एक महान उपकरण है और यह मुफ़्त है!


2

XML को XmlDocument वर्ग के साथ लिखना

//itemValues is collection of items in Key value pair format
//fileName i name of XML file which to creatd or modified with content
    private void WriteInXMLFile(System.Collections.Generic.Dictionary<string, object> itemValues, string fileName)
    {
        string filePath = "C:\\\\tempXML\\" + fileName + ".xml";
        try
        {

            if (System.IO.File.Exists(filePath))
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(filePath);                   

                XmlNode rootNode = doc.SelectSingleNode("Documents");

                XmlNode pageNode = doc.CreateElement("Document");
                rootNode.AppendChild(pageNode);


                foreach (string key in itemValues.Keys)
                {

                    XmlNode attrNode = doc.CreateElement(key);
                    attrNode.InnerText = Convert.ToString(itemValues[key]);
                    pageNode.AppendChild(attrNode);
                    //doc.DocumentElement.AppendChild(attrNode);

                }
                doc.DocumentElement.AppendChild(pageNode);
                doc.Save(filePath);
            }
            else
            {
                XmlDocument doc = new XmlDocument();
                using(System.IO.FileStream fs = System.IO.File.Create(filePath))
                {
                    //Do nothing
                }

                XmlNode rootNode = doc.CreateElement("Documents");
                doc.AppendChild(rootNode);
                doc.Save(filePath);

                doc.Load(filePath);

                XmlNode pageNode = doc.CreateElement("Document");
                rootNode.AppendChild(pageNode);

                foreach (string key in itemValues.Keys)
                {                          
                    XmlNode attrNode = doc.CreateElement(key);                           
                    attrNode.InnerText = Convert.ToString(itemValues[key]);
                    pageNode.AppendChild(attrNode);
                    //doc.DocumentElement.AppendChild(attrNode);

                }
                doc.DocumentElement.AppendChild(pageNode);

                doc.Save(filePath);

            }
        }
        catch (Exception ex)
        {

        }

    }

OutPut look like below
<Dcouments>
    <Document>
        <DocID>01<DocID>
        <PageName>121<PageName>
        <Author>Mr. ABC<Author>
    <Dcoument>
    <Document>
        <DocID>02<DocID>
        <PageName>122<PageName>
        <Author>Mr. PQR<Author>
    <Dcoument>
</Dcouments>

1

यदि आप डिज़ाइनर में टाइप किया हुआ डेटासेट बनाते हैं तो आपको स्वचालित रूप से एक xsd मिलता है, एक जोरदार टाइप की गई वस्तु, और कोड की एक लाइन के साथ xml को लोड और सेव कर सकता है।


मुझे डेटासेट के साथ बड़ी सफलता मिली है। वे डेटाबेस के साथ भी बहुत दोस्ताना हैं।
उपयोगकर्ता 1

1

C # प्रोग्रामर के रूप में मेरी व्यक्तिगत राय, यह है कि C # में XML से निपटने का सबसे अच्छा तरीका कोड के उस हिस्से को VB .NET प्रोजेक्ट में सौंपना है। .NET 3.5 में, VB .NET में XML लिटरल्स हैं, जो XML के साथ बहुत अधिक सहज व्यवहार करते हैं। यहाँ देखें, उदाहरण के लिए:

Visual Basic में LINQ to XML का अवलोकन

(VB कोड प्रदर्शित करने के लिए पृष्ठ सेट करना सुनिश्चित करें, C # कोड नहीं।)

मैं बाकी प्रोजेक्ट को C # में लिखूंगा, लेकिन संदर्भित VB प्रोजेक्ट में XML को हैंडल करूंगा।


यह केवल XML शाब्दिक vb के लिए swtich के लायक नहीं है। एक्सएमएल केवल शाब्दिक के साथ सौदा करता है। यदि xml को एक पैरामीटर के रूप में पास किया जाता है, तो XML शाब्दिक समर्थन आपको अधिक लाभ नहीं देता है। इसके बजाय, vb.net की विरासत वाक्य विन्यास C # के सुखद प्रोग्रामिंग अनुभव को बर्बाद कर देगा।
गक्क्निबग

0

nyxtom,

उदाहरण 1 में "डॉक" और "एक्सडॉक" मैच नहीं होना चाहिए?

XDocument **doc** = XDocument.Load(pathToXml);
List<Person> people = (from xnode in **xdoc**.Element("People").Elements("Person")
                   select new Person
                   {
                       Name = xnode.Attribute("Name").Value
                   }).ToList();

मैंने उस उत्तर पर अनुमोदन के लिए एक संपादन प्रस्तुत किया है जिसका आप उल्लेख कर रहे हैं, हालांकि यह वास्तव में एक टिप्पणी होना चाहिए, उत्तर नहीं।
डेविड थॉम्पसन

धन्यवाद डेविड। सहमत, यह मुझे उस समय टिप्पणी करने की अनुमति नहीं देगा। यकीन नहीं है कि क्यों।
mokumaxCraig

0

Cookey का उत्तर अच्छा है ... लेकिन यहाँ एक XSD (या XML) से एक जोरदार टाइप की गई वस्तु बनाने और कोड की कुछ पंक्तियों में क्रमबद्ध / डीसर्लाइज़ करने के बारे में विस्तृत निर्देश दिए गए हैं:

अनुदेश


"जिस पृष्ठ को आप ढूंढ रहे थे वह मौजूद नहीं है।" :(
इयान ग्रिंगर 16

0

यदि आपको कभी भी XmlNode<=> XNode<=> XElement
(जैसे कि LINQ का उपयोग करने के लिए) के बीच डेटा परिवर्तित करने की आवश्यकता है, तो यह एक्सटेंशन आपके लिए उपयोगी हो सकता है:

public static class MyExtensions
{
    public static XNode GetXNode(this XmlNode node)
    {
        return GetXElement(node);
    }

    public static XElement GetXElement(this XmlNode node)
    {
        XDocument xDoc = new XDocument();
        using (XmlWriter xmlWriter = xDoc.CreateWriter())
            node.WriteTo(xmlWriter);
        return xDoc.Root;
    }

    public static XmlNode GetXmlNode(this XElement element)
    {
        using (XmlReader xmlReader = element.CreateReader())
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(xmlReader);
            return xmlDoc;
        }
    }

    public static XmlNode GetXmlNode(this XNode node)
    {
        return GetXmlNode(node);
    }
}

उपयोग:

XmlDocument MyXmlDocument = new XmlDocument();
MyXmlDocument.Load("MyXml.xml");
XElement MyXElement = MyXmlDocument.GetXElement(); // Convert XmlNode to XElement
List<XElement> List = MyXElement.Document
   .Descendants()
   .ToList(); // Now you can use LINQ
...
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.