Para aqueles que também estão tentando encontrar uma solução mais viável, ignore isso. É uma biblioteca .NET antiga. Em vez disso, use o XDocument, e você evitará que arrancar seus olhos de frustração
AER
Respostas:
180
O principal meio de leitura e gravação em C # 2.0 é feito por meio da classe XmlDocument . Você pode carregar a maioria de suas configurações diretamente no XmlDocument por meio do XmlReader que ele aceita.
Carregando XML diretamente
XmlDocument document = new XmlDocument();
document.LoadXml("<People><PersonName='Nick' /><PersonName='Joe' /></People>");
Carregando XML de um arquivo
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 XPath.
Lendo um documento XML usando XPath (usando 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 você precisa trabalhar com documentos XSD para validar um documento XML, você pode usar isso.
Validando documentos XML em relação a esquemas XSD
Validando XML contra XSD em cada Nó (ATUALIZAÇÃO 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()) { }
privatevoidsettings_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
}
No .NET 3.5, você usa o XDocument para executar tarefas semelhantes. A diferença, entretanto, é que você tem a vantagem de realizar Consultas Linq para selecionar os dados exatos de que precisa. Com a adição de inicializadores de objeto, você pode criar uma consulta que retorna até mesmo objetos de sua própria definição diretamente na própria consulta.
XDocument doc = XDocument.Load(pathToXml);
List<Person> people = (from xnode in doc.Element("People").Elements("Person")
selectnew Person
{
Name = xnode.Attribute("Name").Value
}).ToList();
(ATUALIZAÇÃO 2)
Uma boa maneira no .NET 3.5 é usar o XDocument para criar XML abaixo. 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")
)
)
);
Você pode querer apontar que está usando o XDocument no último exemplo, pois o XDocument é bastante diferente do XmlDocument
Aaron Powell,
2
Correção; não há C # 3.5; você quer dizer .NET 3.5 e C # 3.0
Marc Gravell
ah, e os [inicializadores de objeto] "on the fly" funcionariam basicamente da mesma forma com C # 3.0 e XmlDocument - ainda uma boa resposta, embora (+1)
Marc Gravell
Vale a pena mencionar que se você estiver carregando um documento para consultar com XPath (e não para editar), usar um XPathDocument será muito mais eficiente
Oliver Hallam
Esta validação de esquema é feita nó por nó? Se não, existe uma maneira de fazer isso nó por nó?
Malik Daud Ahmad Khokhar
30
Depende do tamanho; para xml de tamanho 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, você pode carregar o xml usando um XmlReader , e um XmlReader aceita (para criar ) um XmlReaderSettings . Os objetos XmlReaderSettings têm uma propriedade Schemas que pode ser usada para executar a validação xsd (ou dtd).
Para escrever xml, as mesmas coisas se aplicam, observando que é um pouco mais fácil fazer o layout do conteúdo com LINQ-to-XML (XDocument) do que o XmlDocument mais antigo.
No entanto, para xml enorme, um DOM pode consumir muita memória e, nesse caso, você pode precisar usar XmlReader / XmlWriter diretamente.
Finalmente, para manipular xml, você pode querer usar XslCompiledTransform (uma camada xslt).
A alternativa para trabalhar com xml é trabalhar com um modelo de objeto; você pode usar xsd.exe para criar classes que representam um modelo compatível com xsd e simplesmente carregar o xml como objetos , manipulá-lo com OO e serializar esses objetos novamente; você faz isso com XmlSerializer .
Para manipular (adicionar / suprimir elementos) um grande documento XML (40k linhas). Qual é a melhor maneira? Eu costumava usar LINQ-to-XML.
Neyoh
12
A resposta da nyxtom é muito boa. Eu adicionaria algumas coisas a ele:
Se você precisar de acesso somente leitura a um documento XML, XPathDocumenté um objeto muito mais leve do que XmlDocument.
A desvantagem de usar XPathDocumenté que você não pode usar os métodos SelectNodese SelectSingleNodemétodos familiares de XmlNode. Em vez disso, você deve usar as ferramentas que o IXPathNavigablefornece: use CreateNavigatorpara criar um XPathNavigatore use XPathNavigatorpara criar XPathNodeIterators para iterar nas listas de nós que você encontrar por meio do XPath. Isso geralmente requer mais algumas linhas de código do que os XmlDocumentmétodos.
Mas: as classes XmlDocumente XmlNodeimplementam IXPathNavigable, portanto, qualquer código que você escrever para usar esses métodos em um XPathDocumenttambém funcionará em um XmlDocument. Se você se acostumar a escrever contra IXPathNavigable, seus métodos podem funcionar contra qualquer um dos objetos. (É por isso que usar XmlNodee XmlDocumentem assinaturas de método é sinalizado pelo FxCop.)
Lamentavelmente, XDocumentand XElement(and XNodeand XObject) não implementam IXPathNavigable.
Outra coisa que não está presente na resposta de nyxtom é XmlReader. Você geralmente usa XmlReaderpara evitar a sobrecarga de analisar o fluxo XML em um modelo de objeto antes de começar a processá-lo. Em vez disso, use um XmlReaderpara processar o fluxo de entrada um nó XML por vez. Esta é essencialmente a resposta do .NET para SAX. Ele permite que você escreva um código muito rápido para processar documentos XML muito grandes.
XmlReader também fornece a maneira mais simples de processar fragmentos de documentos XML, por exemplo, o fluxo de elementos XML sem nenhum elemento de inclusão que a opção FOR XML RAW do SQL Server retorna.
O código que você escreve usando XmlReadergeralmente está fortemente acoplado ao formato do XML que está lendo. Usar 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.
Em primeiro lugar, conheça as novas classes XDocument e XElement , porque são uma melhoria em relação à família XmlDocument anterior.
Eles funcionam com LINQ
Eles são mais rápidos e mais leves
No entanto , talvez você ainda precise usar as classes antigas para trabalhar com código legado - particularmente proxies gerados anteriormente. Nesse caso, você precisará se familiarizar com alguns padrões para interoperar entre essas classes de manipulação de XML.
Acho que sua pergunta é bastante ampla e exigiria muito em uma única resposta para fornecer detalhes, mas esta é a primeira resposta geral em que pensei e serve como um começo.
Se você criar um conjunto de dados tipado no designer, obterá automaticamente um xsd, um objeto fortemente tipado, e poderá carregar e salvar o xml com uma linha de código.
Tive grande sucesso com o DataSet. Eles também são muito amigáveis com bancos de dados.
Usuário1
1
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 projeto VB .NET. No .NET 3.5, o VB .NET possui XML Literals, o que torna o tratamento de XML muito mais intuitivo. Veja aqui, por exemplo:
Não vale a pena mudar para vb apenas para XML literal. XML lida apenas com literais. Se o xml for passado como um parâmetro, o suporte literal XML não oferece muitos benefícios. Em vez disso, a sintaxe legada do vb.net arruinará a feliz experiência de programação do C #.
Gqqnbig
0
nyxtom,
"Doc" e "xdoc" não deveriam corresponder no Exemplo 1?
XDocument **doc** = XDocument.Load(pathToXml);
List<Person> people = (from xnode in **xdoc**.Element("People").Elements("Person")
selectnew Person
{
Name = xnode.Attribute("Name").Value
}).ToList();
Enviei uma edição para aprovação da resposta à qual você está se referindo; no entanto, deveria ser um comentário, não uma resposta.
David Thompson
Obrigado David. Concordo, não me permitiria comentar na época. Não sei por quê.
mokumaxCraig
0
A resposta de Cookey é boa ... mas aqui estão instruções detalhadas sobre como criar um objeto fortemente tipado a partir de um XSD (ou XML) e serializar / desserializar em algumas linhas de código:
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
...
Respostas:
O principal meio de leitura e gravação em C # 2.0 é feito por meio da classe XmlDocument . Você pode carregar a maioria de suas configurações diretamente no XmlDocument por meio do XmlReader que ele aceita.
Carregando XML diretamente
XmlDocument document = new XmlDocument(); document.LoadXml("<People><Person Name='Nick' /><Person Name='Joe' /></People>");
Carregando XML de um arquivo
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 XPath.
Lendo um documento XML usando XPath (usando 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 você precisa trabalhar com documentos XSD para validar um documento XML, você pode usar isso.
Validando documentos XML em relação a esquemas 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ó (ATUALIZAÇÃO 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 }
Escrevendo 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();
(ATUALIZAÇÃO 1)
No .NET 3.5, você usa o XDocument para executar tarefas semelhantes. A diferença, entretanto, é que você tem a vantagem de realizar Consultas Linq para selecionar os dados exatos de que precisa. Com a adição de inicializadores de objeto, você pode criar uma consulta que retorna até mesmo objetos de sua própria definição diretamente na própria consulta.
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();
(ATUALIZAÇÃO 2)
Uma boa maneira no .NET 3.5 é usar o XDocument para criar XML abaixo. 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>
Se tudo o mais falhar, você pode verificar este artigo do MSDN que tem muitos exemplos que discuti aqui e mais. http://msdn.microsoft.com/en-us/library/aa468556.aspx
fonte
Depende do tamanho; para xml de tamanho 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, você pode carregar o xml usando um XmlReader , e um XmlReader aceita (para criar ) um XmlReaderSettings . Os objetos XmlReaderSettings têm uma propriedade Schemas que pode ser usada para executar a validação xsd (ou dtd).
Para escrever xml, as mesmas coisas se aplicam, observando que é um pouco mais fácil fazer o layout do conteúdo com LINQ-to-XML (XDocument) do que o XmlDocument mais antigo.
No entanto, para xml enorme, um DOM pode consumir muita memória e, nesse caso, você pode precisar usar XmlReader / XmlWriter diretamente.
Finalmente, para manipular xml, você pode querer usar XslCompiledTransform (uma camada xslt).
A alternativa para trabalhar com xml é trabalhar com um modelo de objeto; você pode usar xsd.exe para criar classes que representam um modelo compatível com xsd e simplesmente carregar o xml como objetos , manipulá-lo com OO e serializar esses objetos novamente; você faz isso com XmlSerializer .
fonte
A resposta da nyxtom é muito boa. Eu adicionaria algumas coisas a ele:
Se você precisar de acesso somente leitura a um documento XML,
XPathDocument
é um objeto muito mais leve do queXmlDocument
.A desvantagem de usar
XPathDocument
é que você não pode usar os métodosSelectNodes
eSelectSingleNode
métodos familiares deXmlNode
. Em vez disso, você deve usar as ferramentas que oIXPathNavigable
fornece: useCreateNavigator
para criar umXPathNavigator
e useXPathNavigator
para criarXPathNodeIterator
s para iterar nas listas de nós que você encontrar por meio do XPath. Isso geralmente requer mais algumas linhas de código do que osXmlDocument
métodos.Mas: as classes
XmlDocument
eXmlNode
implementamIXPathNavigable
, portanto, qualquer código que você escrever para usar esses métodos em umXPathDocument
também funcionará em umXmlDocument
. Se você se acostumar a escrever contraIXPathNavigable
, seus métodos podem funcionar contra qualquer um dos objetos. (É por isso que usarXmlNode
eXmlDocument
em assinaturas de método é sinalizado pelo FxCop.)Lamentavelmente,
XDocument
andXElement
(andXNode
andXObject
) não implementamIXPathNavigable
.Outra coisa que não está presente na resposta de nyxtom é
XmlReader
. Você geralmente usaXmlReader
para evitar a sobrecarga de analisar o fluxo XML em um modelo de objeto antes de começar a processá-lo. Em vez disso, use umXmlReader
para processar o fluxo de entrada um nó XML por vez. Esta é essencialmente a resposta do .NET para SAX. Ele permite que você escreva um código muito rápido para processar documentos XML muito grandes.XmlReader
também fornece a maneira mais simples de processar fragmentos de documentos XML, por exemplo, o fluxo de elementos XML sem nenhum elemento de inclusão que a opção FOR XML RAW do SQL Server retorna.O código que você escreve usando
XmlReader
geralmente está fortemente acoplado ao formato do XML que está lendo. Usar 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 usarXmlReader
, você realmente precisa.fonte
XPathNavigator CreateNavigator(this XNode node)
para criar umXPathNavigator
de umXNode
(que inclui a classe derivadaXDocument
).Em primeiro lugar, conheça as novas classes XDocument e XElement , porque são uma melhoria em relação à família XmlDocument anterior.
No entanto , talvez você ainda precise usar as classes antigas para trabalhar com código legado - particularmente proxies gerados anteriormente. Nesse caso, você precisará se familiarizar com alguns padrões para interoperar entre essas classes de manipulação de XML.
Acho que sua pergunta é bastante ampla e exigiria muito em uma única resposta para fornecer detalhes, mas esta é a primeira resposta geral em que pensei e serve como um começo.
fonte
101 amostras 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 torna o XML fácil.
fonte
Se você está trabalhando em .NET 3.5 e não tem medo de código experimental, pode verificar LINQ to 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 regras embutidas do XSD).
Em seguida, ele tem a capacidade de gravar diretamente em um arquivo e ler de um arquivo, garantindo que ele esteja em conformidade com as regras XSD.
Definitivamente, sugiro ter um XSD para qualquer documento XML com o qual você trabalha:
Acho que Liquid XML Studio é uma ótima ferramenta para gerar XSDs e é grátis!
fonte
Escrevendo 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>
fonte
Se você criar um conjunto de dados tipado no designer, obterá automaticamente um xsd, um objeto fortemente tipado, e poderá carregar e salvar o xml com uma linha de código.
fonte
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 projeto VB .NET. No .NET 3.5, o VB .NET possui XML Literals, o que torna o tratamento de XML muito mais intuitivo. Veja aqui, por exemplo:
Visão geral do LINQ to XML no Visual Basic
(Certifique-se de definir a página para exibir o código VB, não o código C #.)
Eu escreveria o resto do projeto em C #, mas lidaria com o XML em um projeto VB referenciado.
fonte
nyxtom,
"Doc" e "xdoc" não deveriam 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();
fonte
A resposta de Cookey é boa ... mas aqui estão instruções detalhadas sobre como criar um objeto fortemente tipado a partir de um XSD (ou XML) e serializar / desserializar em algumas linhas de código:
Instruções
fonte
Se você precisar converter dados entre
XmlNode
<=>XNode
<=>XElement
(por exemplo, para usar o LINQ), essas extensões podem ser úteis para você:
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); } }
Uso:
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 ...
fonte