2010-09-20 28 views
9

Supongamos que tengo el siguiente documento XML.Obtener valor de atributo de un documento XML utilizando C#

<reply success="true">More nodes go here</reply> 

Cómo obtener el valor del atributo success, que en este caso sería la cadena "true".

+0

¿Debe la solución usar 'XmlDocument' o cualquier otra API específica de procesamiento XML? –

+0

@ Daniel: incluso antes de ir allí: http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 ;-) –

+0

@Isak: ¡No tenía intención de ir a la ruta de RegEx! La pregunta habla de un "Documento XML" que sugiere el uso de una DOM API (es decir, 'XmlDocument') pero yo estaba preguntando si era necesario o si una API basada en stream/SAX como' XmlReader' era aceptable en su lugar. –

Respuesta

22

me gustaría probar algo como esto:

XmlDocument doc = new XmlDocument(); 
doc.LoadXml("<reply success=\"true\">More nodes go here</reply>"); 

XmlElement root = doc.DocumentElement; 

string s = root.Attributes["success"].Value; 
+0

también se podría tratar de obtener el atributo por su nombre: root.Attributes [ "éxito"] Valor –

+1

Por lo general es muy mala práctica de atributos de acceso por posición, porque por definición el orden de los atributos de los elementos XML no es significativo.. En este caso trivial, funciona porque solo hay un atributo, pero eso solo es tener suerte. –

+0

Tienes razón, ya sugerí la alternativa en mi primer comentario. Ahora edité mi publicación original para mostrarla. –

-1

Aquí hay una solución alternativa usando XmlReader que puede ser un poco más eficiente que el uso XmlDoument aunque eso es proably insignificante sobre un documento tan pequeño XML

string input = "<reply success=\"true\">More nodes go here</reply>"; 

using (XmlReader xmlReader = XmlReader.Create(new StringReader(input))) 
{ 
    xmlReader.MoveToContent(); 
    string success = xmlReader.GetAttribute("success"); 
    Console.WriteLine(success); 
} 
+1

Guau, tres respuestas seguidas que hacen lo mismo incorrecto de tres maneras diferentes. –

+0

Creo que la impresión general que dio la pregunta original fue que se supone que debemos encontrar el valor para el primer atributo. Ahora he corregido mi código para hacer la cosa más útil en general que sugirió. – explorer

+0

@Robert: es suficiente, la respuesta ha cambiado –

2
using System; 
    using System.Linq; 
    using System.Xml.Linq; 

    class MyClass 
    { 
     static void Main(string[] args) 
     { 
      XElement xmlcode = 
      XElement.Parse("<reply success=\"true\">More nodes go </reply>"); 

      var successAttributes = 
       from attribute in xmlcode.Attributes() 
       where attribute.Name.LocalName=="success" 
       select attribute ; 

      if(successAttributes.Count()>0) 
      foreach (var sa in successAttributes) 
      { 
       Console.WriteLine(sa.Value);   
      } 
      Console.ReadLine(); 
     } 
    } 
+0

Ver mi comentario sobre la respuesta de Rewinder; esta respuesta tiene exactamente el mismo problema. Funcionará en este caso trivial, pero es una práctica muy mala en general. –

+0

Sí, tienes razón. Edité el código para que busque e imprima el valor de todos los valores de los atributos de 'éxito' en el fragmento de XML, independientemente de su orden o ubicación. Ahora devuelva mi Zero :) – explorer

8

Si carga el XML en un XmlDocument, hay cualquier cantidad de maneras de obtener el valor del atributo. Se podría utilizar XPath para encontrar el atributo:

XmlAttribute a = doc.SelectSingleNode("/reply/@success"); 
Console.Write(a.Value); 

Si ya tiene el XmlElement que el atributo aparece en (que en este caso es el elemento de documento), a continuación, puedes utilizar GetAttribute:

Console.Write(doc.DocumentElement.GetAttribute("success")); 

hay enfoques similares si está utilizando o XPathDocumentXmlReader o XDocument.

En todos los casos, sin embargo, desea obtener el atributo por su nombre , no su posición. En su caso de prueba solo hay un atributo; en cualquier aplicación del mundo real, es probable que existan varios atributos, y el orden de atributos en XML no es significativo. Estos dos elementos son semánticamente equivalentes:

<a foo='true' bar='false'/> 

<a bar='false' foo='true'/> 

Incluso no saben que el analizador XML presentará atributos a que en el mismo orden en que aparecen en el documento; dependiendo de la implementación, el analizador puede entregárselos en orden alfabético o en orden aleatorio. (He visto tanto.)

+0

Pero estamos hablando de C#/.NET específicamente aquí y no hay mención en la documentación de MS que los atributos 'XmlReader' o' XmlDocument' indexen atributos en cualquier cosa que no sea el documento/orden de entrada así que si el requerimiento era para "obtener el primer atributo que aparece en el XML de entrada", esto se puede lograr buscando el atributo con el índice cero. Por supuesto, la pregunta no es pedir el "primer" atributo, entonces es correcto en este caso usar el nombre del atributo en lugar del índice. –

+1

No hay garantía en la documentación de MS de que 'XmlDocument' (en realidad,' XmlNamedNodeMap') indexe los atributos en cualquier orden determinista. Hay ejemplos que muestran que los nodos están indexados en el orden en que se agregan al mapa. Pero esos ejemplos están en esta página: http://msdn.microsoft.com/en-us/library/7sf9z378.aspx. ¿Y qué, orar, es la primera palabra en el título? –

1
var at = 
XElement.Parse("<reply success=\"true\">More nodes go </reply>").Attribute("success"); 
if (at != null) Console.Write(at.Value); 
0

El siguiente código funciona para mí.

String strXML = "<reply success=\"true\">More nodes go here</reply>"; 

    using (XmlReader reader = XmlReader.Create(new StringReader(strXML))) 
    { 
      reader.ReadToFollowing("reply"); 
      reader.MoveToContent(); 
      string strValue = reader.GetAttribute("success"); 
      Console.WriteLine(strValue); 
    } 
Cuestiones relacionadas