Como se analisa arquivos XML? [fechadas]

492

Existe um método simples de analisar arquivos XML em c #? Se sim, o que?

domoaringatoo
fonte
você poderia usar esta implementação: stackoverflow.com/a/34813985/5784646
Eulogy
Ok, eu reabri isso. A duplicata era uma solução XML Reader, onde se trata de analisar arquivos XML. O possível duplicado pode ser visto nas perguntas edit history ps @ GeorgeorgeStocker
Jeremy Thompson
1
@ JeremyThompson Uma das razões pelas quais essa duplicata é a outra pergunta tem uma resposta muito melhor. A resposta principal sendo uma resposta simples "somente link" não é útil.
George Stocker
1
@GeorgeStocker, as perguntas são diferentes o suficiente para coexistir e ambas têm ótimas respostas, e as aceitas estão usando tecnologias diferentes. É por isso que votei em deixar isso em aberto, eu sei que esse aceito é apenas um link, mas é MSDN e foi escrito antes que era inaceitável, espero que um efeito colateral da reabertura esteja animando Jon um pouco, leia seu perfil . Enfim aplausos.
21416 Jeremy Thompson

Respostas:

245

Eu usaria o LINQ to XML se você estiver no .NET 3.5 ou superior.

Jon Galloway
fonte
314

É muito simples. Sei que esses são métodos padrão, mas você pode criar sua própria biblioteca para lidar com isso muito melhor.

aqui estão alguns exemplos:

XmlDocument xmlDoc= new XmlDocument(); // Create an XML document object
xmlDoc.Load("yourXMLFile.xml"); // Load the XML document from the specified file

// Get elements
XmlNodeList girlAddress = xmlDoc.GetElementsByTagName("gAddress");
XmlNodeList girlAge = xmlDoc.GetElementsByTagName("gAge"); 
XmlNodeList girlCellPhoneNumber = xmlDoc.GetElementsByTagName("gPhone");

// Display the results
Console.WriteLine("Address: " + girlAddress[0].InnerText);
Console.WriteLine("Age: " + girlAge[0].InnerText);
Console.WriteLine("Phone Number: " + girlCellPhoneNumber[0].InnerText);

Além disso, existem outros métodos para trabalhar. Por exemplo, aqui . E acho que não há um método melhor para fazer isso; você sempre precisa escolher por si mesmo, o que é mais adequado para você.

Lukas Šalkauskas
fonte
47
+1 por mencionar o XmlDocument, que é muito mais conveniente do que as interfaces de serialização em alguns casos. Se você estiver atrás de um elemento específico, poderá acessar elementos filho com o indexador: xmlDoc ["Root"], e estes podem ser encadeados: xmlDoc ["Root"] ["Folder"] ["Item"] hierarquia (embora seja sensato para validar que estes elementos existem na realidade)
Jason Williams
1
InnerTextaqui obtém o valor desse nó, concatenado com todos os valores dos nós filhos - certo? Parece uma coisa estranha de querer.
Don Cheadle
17
Um programador com uma lista de amigas? Travessuras!
E. van Putten
1
@ E.vanPutten não nos dias de hoje. Não é a vingança dos nerds
#
@DonCheadle Se você não está esperando lá para ser os nós filho, então InnerTextsó vai retornar o valor do nó - que é o que eu (e provavelmente todo mundo lendo esta questão) estou analisando o XML para encontrar, em primeiro lugar.
F1Krazy 17/10/19
48

Use um bom esquema XSD para criar um conjunto de classes com xsd.exe e use um XmlSerializerpara criar uma árvore de objetos a partir do seu XML e vice-versa. Se você tiver poucas restrições em seu modelo, você pode até tentar criar um mapeamento direto entre as classes de modelo e o XML com os atributos Xml *.

um artigo introdutório sobre serialização de XML no MSDN.

Dica de desempenho: construir um XmlSerializeré caro. Mantenha uma referência à sua XmlSerializerinstância se você pretende analisar / gravar vários arquivos XML.

David Schmitt
fonte
5
Um bom exemplo é o "Exemplo de pedido de compra" no meio deste exemplo da microsoft. msdn.microsoft.com/en-us/library/58a18dwa.aspx . Você evita ter que criar um esquema - sua classe c # é o esquema, adornado com atributos C #.
precisa saber é o seguinte
25

Se você estiver processando uma grande quantidade de dados (muitos megabytes), deseja usar o XmlReaderfluxo para analisar o XML.

Qualquer outra coisa ( XPathNavigator, XElement, XmlDocumente até mesmo XmlSerializerse você manter o gráfico completo objeto gerado) resultará em alto uso da memória e também um tempo de carregamento muito lento.

Obviamente, se você precisar de todos os dados na memória de qualquer maneira, poderá não ter muita escolha.

Simon Steele
fonte
10

Recentemente, fui solicitado a trabalhar em um aplicativo que envolvia a análise de um documento XML e concordo com Jon Galloway que a abordagem baseada em LINQ to XML é, na minha opinião, a melhor. No entanto, tive que cavar um pouco para encontrar exemplos úteis, portanto, sem mais delongas, aqui estão alguns!

Quaisquer comentários bem-vindos, pois esse código funciona, mas pode não ser perfeito, e eu gostaria de saber mais sobre a análise de XML para este projeto!

public void ParseXML(string filePath)  
{  
    // create document instance using XML file path
    XDocument doc = XDocument.Load(filePath);

    // get the namespace to that within of the XML (xmlns="...")
    XElement root = doc.Root;
    XNamespace ns = root.GetDefaultNamespace();

    // obtain a list of elements with specific tag
    IEnumerable<XElement> elements = from c in doc.Descendants(ns + "exampleTagName") select c;

    // obtain a single element with specific tag (first instance), useful if only expecting one instance of the tag in the target doc
    XElement element = (from c in doc.Descendants(ns + "exampleTagName" select c).First();

    // obtain an element from within an element, same as from doc
    XElement embeddedElement = (from c in element.Descendants(ns + "exampleEmbeddedTagName" select c).First();

    // obtain an attribute from an element
    XAttribute attribute = element.Attribute("exampleAttributeName");
}

Com essas funções, eu era capaz de analisar qualquer elemento e atributo de um arquivo XML sem nenhum problema!

PJRobot
fonte
8

Se você estiver usando o .NET 2.0, tente XmlReadere suas subclasses XmlTextReadere XmlValidatingReader. Eles fornecem uma maneira rápida, leve (uso de memória etc.) e somente encaminhar para analisar um arquivo XML.

Se você precisar de XPathrecursos, tente o XPathNavigator. Se você precisar de todo o documento na memória, tente XmlDocument.

Cinza
fonte
7

Além disso, você pode usar o seletor XPath da seguinte maneira (maneira fácil de selecionar nós específicos):

XmlDocument doc = new XmlDocument();
doc.Load("test.xml");

var found = doc.DocumentElement.SelectNodes("//book[@title='Barry Poter']"); // select all Book elements in whole dom, with attribute title with value 'Barry Poter'

// Retrieve your data here or change XML here:
foreach (XmlNode book in nodeList)
{
  book.InnerText="The story began as it was...";
}

Console.WriteLine("Display XML:");
doc.Save(Console.Out);

a documentação

Joel Harkes
fonte
6

Não sei se existe a "melhor prática para analisar XML". Existem inúmeras tecnologias adequadas para diferentes situações. A maneira de usar depende do cenário concreto.

Você pode ir com o LINQ to XML , XmlReader, XPathNavigatorou até mesmo expressões regulares. Se você elaborar suas necessidades, posso tentar dar algumas sugestões.

aku
fonte
3
regex para xml. seu monstro.
será
3

Você pode analisar o XML usando esta biblioteca System.Xml.Linq. Abaixo está o código de exemplo que eu usei para analisar um arquivo XML

public CatSubCatList GenerateCategoryListFromProductFeedXML()
{
    string path = System.Web.HttpContext.Current.Server.MapPath(_xmlFilePath);

    XDocument xDoc = XDocument.Load(path);

    XElement xElement = XElement.Parse(xDoc.ToString());


    List<Category> lstCategory = xElement.Elements("Product").Select(d => new Category
    {
        Code = Convert.ToString(d.Element("CategoryCode").Value),
        CategoryPath = d.Element("CategoryPath").Value,
        Name = GetCateOrSubCategory(d.Element("CategoryPath").Value, 0), // Category
        SubCategoryName = GetCateOrSubCategory(d.Element("CategoryPath").Value, 1) // Sub Category
    }).GroupBy(x => new { x.Code, x.SubCategoryName }).Select(x => x.First()).ToList();

    CatSubCatList catSubCatList = GetFinalCategoryListFromXML(lstCategory);

    return catSubCatList;
}
Tapan kumar
fonte
1

Você pode usar o ExtendedXmlSerializer para serializar e desserializar.

Instalação Você pode instalar o ExtendedXmlSerializer a partir do nuget ou executar o seguinte comando:

Install-Package ExtendedXmlSerializer

Serialização:

ExtendedXmlSerializer serializer = new ExtendedXmlSerializer();
var obj = new Message();
var xml = serializer.Serialize(obj);

Desserialização

var obj2 = serializer.Deserialize<Message>(xml);

O serializador XML padrão no .NET é muito limitado.

  • Não suporta serialização de classe com referência circular ou classe com propriedade de interface,
  • Não suporta dicionários,
  • Não há mecanismo para ler a versão antiga do XML,
  • Se você deseja criar um serializador personalizado, sua classe deve herdar de IXmlSerializable. Isso significa que sua classe não será uma classe POCO,
  • Não suporta IoC.

O ExtendedXmlSerializer pode fazer isso e muito mais.

O ExtendedXmlSerializer suporta .NET 4.5 ou superior e .NET Core . Você pode integrá-lo ao WebApi e AspCore.

Wojtpl2
fonte
1

Você pode usar o XmlDocument e, para manipular ou recuperar dados de atributos, pode usar as classes Linq to XML.

shaishav shukla
fonte