[c#] C #에서 XML을 다루는 방법

C # 2.0에서 XML 문서, XSD 등을 처리하는 가장 좋은 방법은 무엇입니까?

사용할 클래스 등 XML 문서를 구문 분석하고 만드는 모범 사례는 무엇입니까?

편집 : .Net 3.5 제안도 환영합니다.



답변

C # 2.0에서 읽고 쓰는 기본 방법은 XmlDocument 클래스를 통해 수행됩니다 . 허용되는 XmlReader를 통해 대부분의 설정을 XmlDocument에 직접로드 할 수 있습니다.

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);

XML 문서를 읽는 가장 쉽고 빠른 방법은 XPath를 사용하는 것입니다.

XPath를 사용하여 XML 문서 읽기 (편집 할 수있는 XmlDocument 사용)

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 유효성 검사 (UPDATE 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 쿼리를 수행하는 이점이 있다는 것입니다. 개체 이니셜 라이저를 추가하면 쿼리 자체에서 직접 정의한 개체도 반환하는 쿼리를 만들 수 있습니다.

    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에서 좋은 방법은 XDocument를 사용하여 XML을 만드는 것입니다. 이렇게하면 코드가 원하는 출력과 유사한 패턴으로 나타납니다.

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


답변

크기에 따라 다릅니다. 중소 규모 xml의 경우 XmlDocument (모든 C # /. NET 버전) 또는 XDocument (.NET 3.5 / C # 3.0) 와 같은 DOM 이 확실한 승자입니다. XSD를 사용하기 위해, 당신은 XML이 사용하여로드 할 수 있습니다 XmlReader를을 하고 XmlReader를이 (을 수락 작성 AN) XmlReaderSettings를 . XmlReaderSettings 개체에는 xsd (또는 dtd) 유효성 검사를 수행하는 데 사용할 수 있는 Schemas 속성이 있습니다.

xml을 작성하는 경우에도 동일한 사항이 적용되며, 이전 XmlDocument보다 LINQ-to-XML (XDocument)을 사용하여 콘텐츠를 레이아웃하는 것이 조금 더 쉽습니다.

그러나 거대한 xml의 경우 DOM이 너무 많은 메모리를 꽉 채울 수 있으며,이 경우 XmlReader / XmlWriter를 직접 사용해야 할 수 있습니다.

마지막으로 xml을 조작하기 위해 XslCompiledTransform (xslt 레이어) 을 사용할 수 있습니다 .

xml 작업에 대한 대안은 개체 모델로 작업하는 것입니다. 당신이 사용할 수있는 xsd.exe를 XSD에 호환 모델을 대표하는 클래스를 생성하고, 단순히 XML로드 객체로를 , OO 그것을 조작하고, 다시 그 객체를 직렬화; XmlSerializer 로이 작업을 수행합니다 .


답변

nyxtom의 답변은 매우 좋습니다. 여기에 몇 가지를 추가하겠습니다.

XML 문서에 대한 읽기 전용 액세스가 필요한 경우 XPathDocumentXmlDocument.

사용의 단점은 .NET Framework의 XPathDocument익숙한 방법 SelectNodesSelectSingleNode방법을 사용할 수 없다는 것 입니다 XmlNode. 대신에서 IXPathNavigable제공 하는 도구를 사용해야 합니다. 사용 CreateNavigator하여를 만들고 XPathNavigator를 사용하여 XPathNavigator를 사용하여 XPathNodeIteratorXPath를 통해 찾은 노드 목록을 반복합니다. 일반적으로 XmlDocument메서드 보다 몇 줄 더 많은 코드가 필요 합니다.

그러나 XmlDocumentXmlNode클래스는을 구현 IXPathNavigable하므로에서 해당 메서드를 사용하기 위해 작성한 모든 코드 XPathDocumentXmlDocument. 에 대해 작성하는 데 익숙해지면 IXPathNavigable메서드가 두 객체에 대해 작동 할 수 있습니다. (이것이 FxCop에 의해 using XmlNodeand XmlDocumentin method signatures가 표시되는 이유 입니다.)

유감스럽게도, XDocument그리고 XElement(및 XNodeXObject) 구현하지 마십시오 IXPathNavigable.

nyxtom의 답변에없는 또 다른 것은 XmlReader. 일반적으로 XmlReaderXML 스트림을 처리를 시작하기 전에 객체 모델로 구문 분석하는 오버 헤드를 방지하기 위해 사용 합니다. 대신를 사용 XmlReader하여 입력 스트림을 한 번에 하나의 XML 노드로 처리합니다. 이것은 본질적으로 SAX에 대한 .NET의 대답입니다. 매우 큰 XML 문서를 처리하기위한 매우 빠른 코드를 작성할 수 있습니다.

XmlReader 또한 SQL Server의 FOR XML RAW 옵션이 반환하는 포함 요소가없는 XML 요소 스트림과 같이 XML 문서 조각을 처리하는 가장 간단한 방법을 제공합니다.

사용하는 코드 XmlReader는 일반적으로 읽고있는 XML 형식과 매우 밀접하게 연결됩니다. XPath를 사용하면 코드가 XML에 훨씬 더 느슨하게 결합 될 수 있으므로 일반적으로 올바른 대답입니다. 하지만을 사용해야 XmlReader할 때는 정말 필요합니다.


답변

먼저 새로운 XDocumentXElement 클래스 에 대해 알아보십시오 . 이전 XmlDocument 제품군보다 개선 된 것입니다.

  1. LINQ와 함께 작동합니다.
  2. 더 빠르고 가볍습니다.

그러나 레거시 코드, 특히 이전에 생성 된 프록시로 작업하려면 이전 클래스를 계속 사용해야 할 수 있습니다. 이 경우 이러한 XML 처리 클래스 간의 상호 운용을위한 몇 가지 패턴에 익숙해 져야합니다.

나는 귀하의 질문이 매우 광범위하고 세부 사항을 제공하기 위해 단일 답변에 너무 많은 것이 필요하다고 생각하지만 이것이 제가 생각한 첫 번째 일반적인 대답이며 시작 역할을합니다.


답변

101 Linq 샘플

http://msdn.microsoft.com/en-us/library/bb387098.aspx

Linq to XML 샘플

http://msdn.microsoft.com/en-us/vbasic/bb688087.aspx

그리고 Linq가 XML을 쉽게 만든다고 생각합니다.


답변

.NET 3.5에서 작업 중이고 실험용 코드에 만족하지 않는 경우 LINQ to XSD ( http://blogs.msdn.com/xmlteam/archive/2008/02/21/linq-to- xsd-alpha-0-2.aspx )는 XSD에서 .NET 클래스를 생성합니다 (XSD의 기본 제공 규칙 포함).

그런 다음 XSD 규칙을 준수하는지 확인하여 파일에 직접 쓰고 파일에서 읽을 수 있습니다.

작업하는 모든 XML 문서에 대해 XSD를 사용하는 것이 좋습니다.

  • XML에서 규칙을 적용 할 수 있습니다.
  • 다른 사람들이 XML이 어떻게 구성되는지 볼 수 있습니다.
  • XML 유효성 검사에 사용할 수 있습니다.

Liquid XML Studio는 XSD 생성을위한 훌륭한 도구이며 무료입니다!


답변

XmlDocument 클래스를 사용하여 XML 작성

//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>