Como lidar com XML em C#

Qual é a melhor maneira de lidar com documentos XML, XSD etc Em C# 2.0?

quais as classes a utilizar, etc. Quais são as melhores práticas de processar e fazer documentos XML, etc.

editar:. Net 3. 5 sugestões também são bem-vindas.

 77
Author: Zapnologica, 2008-10-21

12 answers

O principal meio de leitura e escrita em C# 2.0 é feito através da classe XmlDocument. Você pode carregar a maioria de suas configurações diretamente no XmlDocument através do XmlReader que ele aceita.

A carregar o XML directamente

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

A carregar XML de um ficheiro

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

Acho que a maneira mais fácil/rápida de ler um documento XML é usando o XPath.

Ler um documento XML usando o XPath (usando o XmlDocument que nos permite editar)

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

Se precisar de trabalhar com documentos XSD para validar um documento XML, pode usar isto.

A validar documentos XML com os esquemas do XSD

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

Validando XML contra XSD em cada nó (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
}

A escrever um documento XML (manualmente)

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

(actualizar 1)

No. net 3. 5, você usa o XDocument para executar tarefas semelhantes. A diferença no entanto é que você tem a vantagem de realizar consultas Linq para seleccione os dados exactos de que necessita. Com a adição de inicializadores de objetos Você pode criar uma consulta que até mesmo retorna objetos de sua própria definição direita na consulta em si.

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

(actualizar 2)

Uma boa maneira no. net 3. 5 é usar o XDocument para criar o XML está em baixo. Isso faz com que o código apareça em um padrão semelhante à saída desejada.

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

Cria

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

Tudo o resto falha, você pode verificar este artigo MSDN que tem muitos exemplos que discuti aqui e mais. http://msdn.microsoft.com/en-us/library/aa468556.aspx

 166
Author: nyxtom, 2014-12-15 12:10:30

Depende do tamanho; para xml pequeno a médio, um DOM como XmlDocument (qualquer versão C#/. NET) ou XDocument (. net 3.5/C# 3.0) é o vencedor óbvio. Para usar o xsd, poderá carregar o xml usando um XmlReader , e um XmlReader aceita (para Create ) an XmlReaderSettings . Os objectos XmlReaderSettings têm uma propriedade Schemas que pode ser usada para efectuar a validação do xsd (ou dtd).

Para escrever xml, aplicam-se as mesmas coisas, notando que é um pouco mais fácil de colocar conteúdo com LINQ-to-XML (XDocument) do que o XmlDocument mais antigo.

No entanto, para o enorme xml, um DOM pode carregar demasiada memória, caso em que poderá ter de usar o XmlReader/XmlWriter directamente.

Finalmente, para manipular xml, poderá querer usar XslCompiledTransform (uma camada xslt).

A alternativa para trabalhar com xml é trabalhar com um modelo de objecto; você pode usar xsd.exe para criar classes que representar um modelo compatível com o xsd, e simplesmente carregar o xml como objectos, manipulá-lo com OO, e depois serializar esses objectos de novo; faça isto com Xmlserializador.

 29
Author: Marc Gravell, 2008-10-21 05:48:22
A resposta de Nyxtom é muito boa. Eu acrescentava-lhe algumas coisas.

Se precisar de acesso apenas para leitura a um documento XML, {[[0]} é um objecto muito mais leve do que XmlDocument.

A desvantagem de usar {[[0]} é que não pode usar os métodos familiares SelectNodes e SelectSingleNode de XmlNode. Em vez disso, você tem que usar as ferramentas que o IXPathNavigable oferece: use CreateNavigator para criar um XPathNavigator, e use o XPathNavigator para criar XPathNodeIterators para iterar sobre as listas de nós que você encontra através do XPath. Presente geralmente requer mais algumas linhas de código do que os métodos XmlDocument.

Mas: as classes XmlDocument e XmlNode implementam IXPathNavigable, por isso qualquer código que escreva para usar esses métodos NUM XPathDocument também funcionará num XmlDocument. Se você se acostumar a escrever contra IXPathNavigable, seus métodos podem funcionar contra qualquer um dos objetos. (É por isso que o uso de XmlNode e XmlDocument no método as assinaturas são assinaladas pelo FxCop.)

Lamentavelmente, XDocument e XElement (e XNode e XObject) não implementar IXPathNavigable.

Outra coisa. não está presente na resposta de nyxtom é XmlReader. Normalmente usa XmlReader para evitar a sobrecarga de processar a transmissão XML num modelo de objecto antes de começar a processá-la. Em vez disso, você usa um XmlReader para processar o fluxo de entrada de um nó XML de cada vez. Esta é essencialmente a resposta da. NET ao saxofone. Permite-lhe escrever um código muito rápido para processar documentos XML muito grandes.

XmlReader também fornece a forma mais simples de processar fragmentos de documentos XML, por exemplo, o fluxo de elementos XML sem o elemento de inclusão que o servidor de SQL para a opção XML RAW devolve.

O código que se escreve usando XmlReader é geralmente muito estreitamente associado ao formato do XML que está a ler. O uso do XPath permite que seu código seja muito, muito mais vagamente acoplado ao XML, e é por isso que geralmente é a resposta certa. Mas quando você precisa usar XmlReader, você realmente precisa.

 12
Author: Robert Rossney, 2008-10-21 18:51:26

Em primeiro lugar, conheça as novas classes XDocument e XElement, porque são uma melhoria em relação à anterior família XmlDocument.

    Eles trabalham com o LINQ.
  1. Eles são mais rápidos e mais leves

No entanto , você ainda pode ter que usar as classes antigas para trabalhar com o código legado - particularmente os proxies gerados anteriormente. Nesse caso, você terá que se familiarizar com alguns padrões para interoperar entre estas classes de tratamento de XML.

Acho que a sua pergunta é bastante ampla, e exigiria muito numa única resposta para dar detalhes, mas esta é a primeira resposta geral em que pensei, e serve como um começo.
 4
Author: hurst, 2008-10-21 05:47:40

101 amostras de Linq

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

E Linq para amostras XML

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

E acho que o Linq facilita o XML.
 4
Author: emremp, 2008-10-21 06:51:24

Se está a trabalhar no. NET 3.5 e não tem medo de um código experimental, pode verificar o LINQ no XSD ( http://blogs.msdn.com/xmlteam/archive/2008/02/21/linq-to-xsd-alpha-0-2.aspx ) que irá gerar classes. NET a partir de um XSD (incluindo as regras incorporadas no XSD).

Ele então tem a capacidade de escrever diretamente para um arquivo e ler a partir de um arquivo garantindo que ele está em conformidade com as regras do XSD.

Eu definitivamente sugiro ter um XSD para qualquer documento XML que você trabalhe com:

  • permite-lhe fazer cumprir as regras no XML
  • permite que outros vejam como o XML é / será estruturado
  • pode ser usado para a validação de XML
Eu acho que o Liquid XML Studio é uma grande ferramenta para gerar XSD's e é grátis!
 2
Author: Aaron Powell, 2008-10-21 06:49:49

Se você criar um conjunto de dados digitado no designer, então você automaticamente recebe um xsd, um objeto fortemente digitado, e pode carregar e salvar o xml com uma linha de código.

 1
Author: Peter C, 2008-10-21 16:41:01

A minha opinião pessoal, como programador C#, é que a melhor maneira de lidar com XML em C# é delegar essa parte do código a um projecto VB.net. In. net 3.5, VB. net has XML Literals, which make dealing with XML much more intuitive. Veja aqui, por exemplo:

Visão Geral da LINQ para XML no Visual Basic

(Certifique-se que configura a página para mostrar o código VB, não o código C#.)

Eu escreveria o resto do projecto em C#, mas lidaria com o XML num VB referenciado. projecto.
 1
Author: Ryan Lundy, 2010-03-31 18:57:44

A escrever XML com a classe 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
Author: Anil Rathod, 2016-02-09 10:18:31

Nyxtom,

O "doc" e o "xdoc" não devem corresponder no exemplo 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();
 0
Author: mokumaxCraig, 2011-01-29 14:40:03
A resposta do Cookey é boa... mas aqui estão instruções detalhadas sobre como criar um objeto fortemente digitado a partir de um XSD (ou XML) e serializar/deserializar em algumas linhas de código:

Instruções

 0
Author: Steve Horn, 2015-03-26 17:45:40

Se alguma vez precisar de converter dados entre XmlNode XNode XElement
(por exemplo, para usar o LINQ) estas extensões podem ser úteis para si:

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

Utilização:

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
...
 0
Author: Michael Hutter, 2018-08-28 11:21:10