2010-09-20 23 views
9

Załóżmy, że mam następujący dokument XML.Uzyskiwanie wartości atrybutu dokumentu XML przy użyciu C#

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

Jak uzyskać wartość atrybutu success, która w tym przypadku byłaby ciągiem "true".

+0

Czy soluton musi używać 'XmlDocument' lub innego specifc API przetwarzania XML? –

+0

@Daniel: zanim pójdziesz tam: http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 ;-) –

+0

@Isak: Nie miałem zamiaru iść na trasę RegEx! Pytanie mówi o "dokumencie XML", który sugeruje użycie DOM API (tj. 'XmlDocument'), ale pytałem, czy było to wymagane, lub czy API oparty na strumieniu/SAX, taki jak' XmlReader', byłby akceptowalny. –

Odpowiedz

22

chciałbym spróbować coś takiego:

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

Można również spróbować uzyskać atrybut po nazwie: root.Attributes ["succes"]. Wartość –

+1

Zasadniczo bardzo trudno jest uzyskać dostęp do atrybutów według pozycji, ponieważ z definicji kolejność atrybutów na elementach XML nie jest znacząca. W tym trywialnym przypadku działa, ponieważ istnieje tylko jeden atrybut, ale to tylko szczęście. –

+0

Masz rację, już zasugerowałem alternatywę w moim pierwszym komentarzu. Teraz edytowałem mój pierwotny wpis, aby go wyświetlić. –

-1

Oto alternatywne rozwiązanie używając XmlReader które mogą być trochę bardziej wydajny niż przy użyciu XmlDoument chociaż to proably nieistotny na takiej małej dokumentu 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, trzy odpowiedzi z rzędu, które wszystkie robią tę samą niewłaściwą rzecz na trzy różne sposoby. –

+0

Myślę, że ogólne wrażenie, jakie pierwotne pytanie zadało, to że powinniśmy znaleźć wartość pierwszego atrybutu. Poprawiłem teraz swój kod, aby zrobić bardziej ogólnie użyteczną rzecz, którą zasugerowałeś. – explorer

+0

@Robert: Wystarczająco, odpowiedź zmieniona –

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

Zobacz mój komentarz na odpowiedź Rewindera; ta odpowiedź ma dokładnie ten sam problem. Będzie działać w tak trywialnym przypadku, ale ogólnie jest to bardzo zła praktyka. –

+0

Tak, masz rację. Zmodyfikowalem kod, aby wyszukał i wydrukował wartość wszystkich wartości atrybutu "sukces" w kodzie XML bez względu na ich kolejność lub lokalizację. Teraz oddaj moje zero :) – explorer

8

Po załadowaniu pliku XML do formatu XmlDocument istnieje wiele sposobów uzyskania wartości atrybutu. Można używać XPath aby znaleźć atrybut:

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

Jeśli masz już XmlElement że atrybut pojawia się (która w tym przypadku jest elementem dokumentu), to można po prostu użyć GetAttribute:

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

Istnieją podobne podejścia, jeśli używasz XPathDocument lub XmlReader lub XDocument.

We wszystkich przypadkach jednak chcesz uzyskać atrybut według jego nazwy o nazwie, a nie o jego pozycji. W twoim przypadku testowym jest tylko jeden atrybut; w dowolnej aplikacji w świecie rzeczywistym prawdopodobne jest użycie wielu atrybutów, a uporządkowanie atrybutów w XML nie jest znaczące. Te dwa elementy są semantycznie równoważne:

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

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

Ty nawet nie wiesz, że parser XML zaprezentuje atrybuty do was w tej samej kolejności, w jakiej występują w dokumencie; w zależności od implementacji analizator składni może Ci je podać w kolejności alfabetycznej lub losowej. (Widziałem oba.)

+0

Ale mówimy C#/.NET specjalnie tutaj i nie ma żadnej wzmianki w dokumentacji MS, że albo 'XmlReader' albo' XmlDocument' indeksuje atrybuty w czymkolwiek innym niż dokument/kolejność wprowadzania, więc jeśli wymaganie było aby "uzyskać pierwszy atrybut, który pojawia się w wejściowym kodzie XML", można to osiągnąć, szukając atrybutu o indeksie zero. Oczywiście pytanie nie pyta o "pierwszy" atrybut, więc w tym przypadku poprawne jest użycie nazwy atrybutu zamiast indeksu. –

+1

W dokumentacji MS nie ma gwarancji, że 'XmlDocument' (faktycznie,' XmlNamedNodeMap') indeksuje atrybuty w dowolnej deterministycznej kolejności. Istnieją przykłady pokazujące, że węzły są indeksowane w kolejności, w jakiej zostały dodane do mapy. Ale te przykłady znajdują się na tej stronie - http://msdn.microsoft.com/en-us/library/7sf9z378.aspx - a co, proszę, to jest pierwsze słowo w tytule? –

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

Poniższy kod działa dla mnie.

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); 
    } 
Powiązane problemy