Jak odczytać wartość atrybutu z XmlNode w C #?

114

Załóżmy, że mam XmlNode i chcę uzyskać wartość atrybutu o nazwie „Nazwa”. Jak mogę to zrobić?

XmlTextReader reader = new XmlTextReader(path);

XmlDocument doc = new XmlDocument();
XmlNode node = doc.ReadNode(reader);

foreach (XmlNode chldNode in node.ChildNodes)
{
     **//Read the attribute Name**
     if (chldNode.Name == Employee)
     {                    
         if (chldNode.HasChildNodes)
         {
             foreach (XmlNode item in node.ChildNodes)
             { 

             }
         }
      }
}

Dokument XML:

<Root>
    <Employee Name ="TestName">
    <Childs/>
</Root>
Ashish Ashu
źródło

Odpowiedzi:

214

Spróbuj tego:

string employeeName = chldNode.Attributes["Name"].Value;

Edycja: jak wskazano w komentarzach, spowoduje to zgłoszenie wyjątku, jeśli atrybut nie istnieje. Bezpieczna droga to:

var attribute = node.Attributes["Name"];
if (attribute != null){
    string employeeName = attribute.Value;
    // Process the value here
}
Konamiman
źródło
34
Uważaj przy takim podejściu. Myślę, że jeśli atrybut nie jest obecny, dostęp do elementu członkowskiego Value spowoduje wyjątek zerowego odwołania.
Chris Dunaway
3
if (node.Attributes! = null) string workerName = chldNode.Attributes ["Nazwa"]. Wartość;
Omidoo
7
@Omidoo To podejście ma ten sam problem, na przykład z <a x="1" />, który przechodzi test. Może coś takiego var attr = node.Attributes["Name"]; if(attr != null) {...}może zadziałać.
Joel Peltonen
Spójrz na moją odpowiedź poniżej , która omija problem NullException i jest być może bezpieczniejsza w użyciu.
Marco7757
44

Aby rozszerzyć rozwiązanie Konamiman (w tym wszystkie odpowiednie sprawdzenia zerowe), oto co robiłem:

if (node.Attributes != null)
{
   var nameAttribute = node.Attributes["Name"];
   if (nameAttribute != null) 
      return nameAttribute.Value;

   throw new InvalidOperationException("Node 'Name' not found.");
}
Ari Roth
źródło
6
Skróconym sposobem nie uzyskania błędu dla wartości null jest node.Attributes? ["Name"] ?. Value
brandonstrong
1
To prawda, chociaż jedyną rzeczą, na którą zwrócę uwagę, jest to, że chociaż możesz to zrobić w jednej linii (czyniąc to dobrym dla zadania lub czegoś podobnego), jest to nieco mniej elastyczne pod względem kontrolowania, gdy rzucasz wyjątek lub w inny sposób obsłużysz przypadek, w którym węzeł nie ma atrybutów.
Ari Roth
1
Zgoda. Każdy, kto używa metody skróconej, powinien zawsze upewnić się, że nie spowoduje to problemów na późniejszym etapie.
brandonstrong
17

możesz przeglądać wszystkie atrybuty, tak jak robisz to z węzłami

foreach (XmlNode item in node.ChildNodes)
{ 
    // node stuff...

    foreach (XmlAttribute att in item.Attributes)
    {
        // attribute stuff
    }
}
balexandre
źródło
to będzie bardziej korzystne .. :)
SHEKHAR SHETE
4

jeśli potrzebujesz tylko nazw, użyj zamiast tego xpath. Nie ma potrzeby samodzielnego wykonywania iteracji i sprawdzania wartości null.

string xml = @"
<root>
    <Employee name=""an"" />
    <Employee name=""nobyd"" />
    <Employee/>
</root>
";

var doc = new XmlDocument();

//doc.Load(path);
doc.LoadXml(xml);

var names = doc.SelectNodes("//Employee/@name");
phu
źródło
Powyższe metody nie działały dla mojego XML-a (chociaż żałuję, że nie miały). Ta metoda działa! Dzięki!
Frecklefoot
4

Jeśli używasz chldNodeas XmlElementzamiast XmlNode, możesz użyć

var attributeValue = chldNode.GetAttribute("Name");

Wartość zwracana będzie po prostu pustym ciągiem na wypadek, gdyby nazwa atrybutu nie istniała.

Twoja pętla mogłaby wyglądać tak:

XmlDocument document = new XmlDocument();
var nodes = document.SelectNodes("//Node/N0de/node");

foreach (XmlElement node in nodes)
{
    var attributeValue = node.GetAttribute("Name");
}

Spowoduje to zaznaczenie wszystkich węzłów <node>otoczonych <Node><N0de></N0de><Node>tagami, a następnie zapętlenie ich i odczytanie atrybutu „Nazwa”.

Marco7757
źródło
3

Posługiwać się

item.Attributes["Name"].Value;

aby uzyskać wartość.

rahul
źródło
1

Możesz także użyć tego;

string employeeName = chldNode.Attributes().ElementAt(0).Name
komórka
źródło
1

Jeszcze inne rozwiązanie:

string s = "??"; // or whatever

if (chldNode.Attributes.Cast<XmlAttribute>()
                       .Select(x => x.Value)
                       .Contains(attributeName))   
   s =  xe.Attributes[attributeName].Value;

Pozwala również uniknąć wyjątku, gdy oczekiwany atrybut w attributeNamerzeczywistości nie istnieje.

Wyprawiać
źródło