2010-09-20 6 views
9

Angenommen, ich habe das folgende XML-Dokument.Abrufen des Attributwerts eines XML-Dokuments mit C#

Wie erhalten Sie den Wert des Attributs Erfolg, in diesem Fall wäre die Zeichenfolge "wahr".

+0

Muss die Lösung 'XmlDocument' oder eine andere spezifische XML-Verarbeitungs-API verwenden? –

+0

@Daniel: bevor du überhaupt hingehst: http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contented-tags/1732454#1732454 ;-) –

+0

@Isak: Ich hatte nicht die Absicht, die RegEx-Route zu gehen! Die Frage spricht von einem "XML-Dokument", das die Verwendung einer DOM-API vorschlägt (d. H. "XmlDocument"), aber ich fragte, ob dies erforderlich war oder ob stattdessen eine Stream/SAX-basierte API wie "XmlReader" akzeptabel war. –

Antwort

22

Ich würde so etwas wie dies versucht:

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

Sie könnten auch versuchen, das Attribut nach Name zu erhalten: root.Attributes ["succes"]. Wert –

+1

Es ist in der Regel sehr schlecht, auf Attribute nach Position zuzugreifen, da per Definition die Reihenfolge von Attributen in XML-Elementen nicht signifikant ist. In diesem trivialen Fall funktioniert es, weil es nur ein Attribut gibt, aber das ist nur Glück. –

+0

Sie haben Recht, ich habe bereits die Alternative in meinem ersten Kommentar vorgeschlagen. Ich habe jetzt meinen ursprünglichen Beitrag bearbeitet, um es zu zeigen. –

-1

Hier ist eine alternative Lösung XmlReader verwendet, die ein wenig effizienter sein können XmlDoument als die Verwendung obwohl das auf ein so kleines XML-Dokument proably vernachlässigbar ist

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, drei Antworten in Folge, die alle die gleiche falsche Sache auf drei verschiedene Arten tun. –

+0

Ich denke, der allgemeine Eindruck, den die ursprüngliche Frage gab, war, dass wir den Wert für das erste Attribut finden sollten. Ich habe jetzt meinen Code korrigiert, um das allgemein nützlichere zu tun, was Sie vorgeschlagen haben. – explorer

+0

@Robert: fair genug, Antwort geändert –

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

Siehe meinen Kommentar zu Rewinders Antwort; Diese Antwort hat genau das gleiche Problem. Es wird in diesem trivialen Fall funktionieren, ist aber im Allgemeinen sehr schlecht. –

+0

Ja, du hast Recht. Ich habe den Code so bearbeitet, dass er den Wert aller Attributwerte für "Erfolg" im XML-Snippet sucht und druckt, unabhängig von deren Reihenfolge oder Position. Nun gebe ich meine Zero zurück :) – explorer

8

Wenn Sie die XML in eine XmlDocument laden, gibt es eine Reihe von Möglichkeiten, den Wert des Attributs zu erhalten. Sie könnten XPath verwenden das Attribut zu finden:

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

Wenn Sie bereits die XmlElement haben, dass das Attribut auf erscheint (was in diesem Fall das Dokumentelement ist), dann können Sie nur verwenden GetAttribute:

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

Es gibt ähnliche Ansätze, wenn Sie XPathDocument oder XmlReader oder XDocument verwenden.

In allen Fällen möchten Sie jedoch das Attribut durch seine Name erhalten, nicht seine Position. In Ihrem Testfall gibt es nur ein Attribut; In jeder realen Anwendung sind mehrere Attribute wahrscheinlich und die Reihenfolge der Attribute in XML ist nicht signifikant. Diese beiden Elemente sind semantisch äquivalent:

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

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

Sie wissen nicht einmal, dass der XML-Parser Attribute Sie in der gleichen Reihenfolge präsentieren sie im Dokument erscheinen; Abhängig von der Implementierung kann der Parser Ihnen diese in alphabetischer Reihenfolge oder in zufälliger Reihenfolge übergeben. (Ich habe beide gesehen.)

+0

Aber wir sprechen C# /. NET speziell hier und es gibt keine Erwähnung in der MS-Dokumentation, dass entweder 'XmlReader' oder' XmlDocument' Attribute in etwas anderes als Dokument/Eingabe Reihenfolge also wenn die Anforderung war Um "das erste Attribut zu erhalten, das in der Eingabe-XML erscheint", kann dies erreicht werden, indem nach dem Attribut mit dem Index Null gesucht wird. Natürlich fragt die Frage nicht nach dem "ersten" Attribut, so dass es in diesem Fall richtig ist, den Attributnamen anstelle des Indexes zu verwenden. –

+1

Es gibt keine Garantie in der MS-Dokumentation, dass 'XmlDocument' (eigentlich' XmlNamedNodeMap') Attribute in irgendeiner deterministischen Reihenfolge indiziert. Es gibt Beispiele, die zeigen, dass Knoten in der Reihenfolge indiziert werden, in der sie zur Karte hinzugefügt werden. Aber diese Beispiele sind auf dieser Seite - http://msdn.microsoft.com/en-us/library/7sf9z378.aspx - und was, bitte, ist das allererste Wort im Titel? –

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

Der folgende Code funktioniert für mich.

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); 
    } 
Verwandte Themen