2008-09-11 13 views
484

¿Hay un método simple de analizar archivos XML en C#? ¿Entonces qué?¿Cómo se analizan los archivos XML?

+0

puede usar esta implementación: http://stackoverflow.com/a/34813985/5784646 – Eulogy

+0

Ok, reabrí esto. El duplicado era una solución de Lector XML donde se trata de analizar archivos XML. El * posible duplicado * se puede ver en las preguntas [editar] historia ps @GeorgeStocker –

+1

@JeremyThompson Una de las razones por las que este fue un duplicado es que la otra pregunta tiene una respuesta mucho mejor. La respuesta principal es una simple respuesta de "solo enlace" no es útil. –

Respuesta

213

Usaría LINQ to XML si está en .NET 3.5 o superior.

5

No estoy seguro de si existe la "mejor práctica para analizar XML". Existen numerosas tecnologías adecuadas para diferentes situaciones. Qué manera de usar depende del escenario concreto.

Puede ir con LINQ to XML, XmlReader, XPathNavigator o incluso expresiones regulares. Si elaboras tus necesidades, puedo intentar dar algunas sugerencias.

+1

regex para xml. Tú, monstruo. – will

5

Si está utilizando .NET 2.0, intente con XmlReader y sus subclases XmlTextReader y XmlValidatingReader. Proporcionan una forma rápida, liviana (uso de memoria, etc.), solo para reenviar un archivo XML.

Si necesita XPath capacidades, intente con XPathNavigator. Si necesita el documento completo en la memoria, intente XmlDocument.

273

Es muy simple. Sé que estos son métodos estándar, pero puede crear su propia biblioteca para lidiar con eso mucho mejor.

Éstos son algunos ejemplos:

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

También, hay algunas other methods a trabajar. Por ejemplo, here. Y creo que no hay un mejor método para hacer esto; siempre tiene que elegirlo usted mismo, lo que es más adecuado para usted.

+44

+1 por mencionar XmlDocument, que es mucho más conveniente que las interfaces de serialización en algunos casos. Si buscas un elemento específico, puedes acceder a elementos secundarios con el indexador: xmlDoc ["Root"], y estos pueden estar encadenados: xmlDoc ["Root"] ["Folder"] ["Item"] para desenterrar el elemento jerarquía (aunque es sensato validar que estos elementos realmente existen) –

+0

'InnerText' aquí obtiene el valor de ese nodo, concatenado con todos los valores de nodos secundarios - ¿no? Parece una cosa extraña que desear. – mmcrae

+6

¿Un programador con una lista de amigas? ¡Engaños! –

44

Utilice un buen XSD Schema para crear un conjunto de clases con xsd.exe y utilice un XmlSerializer para crear un árbol de objetos a partir de su XML y viceversa. Si tiene pocas restricciones en su modelo, incluso podría tratar de crear una asignación directa entre las clases de su modelo y el XML con los atributos Xml *.

Hay an introductory article about XML Serialisation en MSDN.

Consejo de rendimiento: Construir un XmlSerializer es caro. Mantenga una referencia a su instancia XmlSerializer si tiene la intención de analizar/escribir múltiples archivos XML.

+0

Vea http://www.codeproject.com/KB/cs/xsdtidy.aspx y http://blog.dotnetwiki.org/XsdTidyXSDMappingBeautifier.aspx –

+5

Buen ejemplo es el "Ejemplo de orden de compra" en el medio de este ejemplo de microsoft. http://msdn.microsoft.com/en-us/library/58a18dwa.aspx. Evita tener que crear un esquema: su clase C# es el esquema, adornado con atributos C#. –

21

Si está procesando una gran cantidad de datos (muchos megabytes), entonces quiere usar XmlReader para ver el XML en secuencia.

Cualquier otra cosa (XPathNavigator, XElement, XmlDocument e incluso XmlSerializer si se mantiene la gráfica completa objeto generado) dará lugar a high memory usage y también un tiempo de carga muy lento.

Por supuesto, si necesita todos los datos en la memoria de todos modos, es posible que no tenga muchas opciones.

0

Puede usar ExtendedXmlSerializer para serializar y deserializar.

Instalación Puede instalar ExtendedXmlSerializer de nuget o ejecutar el siguiente comando:

Install-Package ExtendedXmlSerializer 

serialización:

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

Deserialización

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

El serializador XML estándar en .NET es muy limitado.

  • No es compatible con la serialización de la clase con referencia circular o clase con propiedad interfaz,
  • no soporta Diccionarios,
  • No existe un mecanismo para la lectura de la antigua versión de XML,
  • Si quiere crear un serializador personalizado, su clase debe heredar de IXmlSerializable. Esto significa que su clase no será una clase POCO,
  • No es compatible con IoC.

ExtendedXmlSerializer puede hacer esto y mucho más.

apoyo ExtendedXmlSerializer .NET 4.5 o superior y .NET Core. Puede integrarlo con WebApi y AspCore.

2

Puede analizar el XML utilizando esta biblioteca System.Xml.Linq. A continuación se muestra el código de ejemplo que utiliza para analizar un archivo 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; 
} 
0

además se puede utilizar el selector XPath de la siguiente manera (forma sencilla de seleccionar nodos 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); 

the documentation

0

Puede usar XmlDocument y para manipular o recuperar datos de atributos puede Linq a clases XML.

0

Recientemente me han pedido que trabaje en una aplicación que implicó el análisis sintáctico de un documento XML y estoy de acuerdo con Jon Galloway en que el enfoque basado en LINQ to XML es, en mi opinión, el mejor. Sin embargo, tuve que buscar un poco para encontrar ejemplos utilizables, así que sin más preámbulos, ¡aquí hay algunos!

¡Todos los comentarios son bienvenidos ya que este código funciona pero puede no ser perfecto y me gustaría aprender más sobre el análisis de XML para este proyecto!

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

    // set the namespace to that within of the XML (xmlns="...") 
    XNamespace ns = "http://www.example.com/NameSpace"; 

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

Con estas funciones pude analizar sin problemas ningún elemento ni ningún atributo de un archivo XML.

Cuestiones relacionadas