2010-09-20 9 views
9

Supponiamo di avere il seguente documento XML.Ottenere il valore di un attributo di un documento XML utilizzando C#

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

Come ottenere il valore dell'attributo successo, che in questo caso sarebbe la stringa "true".

+0

Il solutone deve utilizzare 'XmlDocument' o qualsiasi altra API di elaborazione XML specifca? –

+0

@Daniel: prima ancora di andare lì: http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 ;-) –

+0

@ Isak: Non avevo intenzione di seguire la rotta RegEx! La domanda parla di un "documento XML" che suggerisce l'utilizzo di un'API DOM (ad esempio 'XmlDocument'), ma mi chiedevo se fosse necessario o se un'API stream/SAX come' XmlReader' fosse accettabile. –

risposta

22

vorrei provare qualcosa di simile:

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

Si potrebbe anche provare a ottenere l'attributo in base al nome: root.Attributes ["successi"]. Valore –

+1

In genere è molto difficile accedere agli attributi in base alla posizione, perché per definizione l'ordinamento degli attributi sugli elementi XML non è significativo. In questo caso banale funziona perché c'è solo un attributo, ma questo è solo essere fortunato. –

+0

Hai ragione, ho già suggerito l'alternativa nel mio primo commento. Ora ho modificato il mio post originale per mostrarlo. –

-1

Ecco una soluzione alternativa utilizzando XmlReader che può essere un po 'più efficiente rispetto all'utilizzo di XmlDoument anche se questo è proably trascurabili su un tale piccolo documento 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

Wow, tre risposte di fila che fanno tutte la stessa cosa sbagliata in tre modi diversi. –

+0

Penso che l'impressione generale che la domanda originale ha dato fosse che dovremmo trovare il valore per il primo attributo. Ora ho corretto il mio codice per fare la cosa più utile che hai suggerito. – explorer

+0

@Robert: abbastanza giusto, risposta modificata –

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

Vedere il mio commento sulla risposta di Rewinder; questa risposta ha esattamente lo stesso problema. Funzionerà in questo caso banale, ma è una pessima pratica in generale. –

+0

Sì, hai ragione. Ho modificato il codice per cercare e stampare il valore di tutti i valori dell'attributo "successo" nello snippet XML indipendentemente dal loro ordine o posizione. Ora restituisci il mio Zero :) – explorer

8

Se si carica l'XML in un XmlDocument, esistono diversi modi per ottenere il valore dell'attributo. Si potrebbe usare XPath per trovare l'attributo:

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

Se hai già la XmlElement che appare l'attributo su (che in questo caso è l'elemento del documento), allora si può solo utilizzare GetAttribute:

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

Esistono approcci simili se si utilizza XPathDocument o XmlReader o XDocument.

In tutti i casi, tuttavia, si desidera ottenere l'attributo tramite il suo nome , non la sua posizione. Nel tuo caso di test c'è un solo attributo; in qualsiasi applicazione del mondo reale sono possibili più attributi e l'ordinamento degli attributi in XML non è significativo. Questi due elementi sono semanticamente equivalenti:

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

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

Tu non sai nemmeno che il parser XML presenterà gli attributi a voi nello stesso ordine in cui appaiono nel documento; a seconda dell'implementazione, il parser può darli in ordine alfabetico o in ordine casuale. (Ho visto entrambi.)

+0

Ma stiamo parlando di C# /. NET specificamente qui e non c'è alcun accenno nella documentazione MS che 'XmlReader' o' XmlDocument' indicizza gli attributi in qualcosa di diverso dall'ordine di documento/input, quindi se il requisito era per "ottenere il primo attributo che appare nell'XML di input", ciò può essere ottenuto cercando l'attributo con l'indice zero. Naturalmente, la domanda non è chiedere l'attributo "primo", quindi in questo caso è corretto utilizzare il nome dell'attributo anziché l'indice. –

+1

Non c'è alcuna garanzia nella documentazione MS che 'XmlDocument' (in realtà,' XmlNamedNodeMap') indicizza gli attributi in qualsiasi ordine deterministico. Ci sono esempi che mostrano che i nodi sono indicizzati nell'ordine in cui vengono aggiunti alla mappa. Ma quegli esempi sono in questa pagina - http://msdn.microsoft.com/en-us/library/7sf9z378.aspx - e cosa, prego, è la prima parola nel titolo? –

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

Il seguente codice funziona per me.

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