Como ler o valor do atributo de XmlNode em c #?

114

Suponha que eu tenha um XmlNode e desejo obter o valor de um atributo denominado "Nome". Como eu posso fazer isso?

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)
             { 

             }
         }
      }
}

Documento XML:

<Root>
    <Employee Name ="TestName">
    <Childs/>
</Root>
Ashish Ashu
fonte

Respostas:

214

Experimente isto:

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

Editar: conforme apontado nos comentários, isso lançará uma exceção se o atributo não existir. A maneira segura é:

var attribute = node.Attributes["Name"];
if (attribute != null){
    string employeeName = attribute.Value;
    // Process the value here
}
Konamiman
fonte
34
Tenha cuidado com esta abordagem. Acho que se o atributo não estiver presente, acessar o membro Value causará uma exceção de referência nula.
Chris Dunaway,
3
if (node.Attributes! = null) string employeeName = chldNode.Attributes ["Name"]. Value;
Omidoo
7
@Omidoo Essa abordagem tem o mesmo problema, por exemplo <a x="1" />, com , que passa no teste. Talvez algo assim var attr = node.Attributes["Name"]; if(attr != null) {...}possa funcionar.
Joel Peltonen
Dê uma olhada na minha resposta abaixo , que contorna o problema NullException e é, talvez ?, mais seguro de usar.
Marco7757
44

Para expandir a solução da Konamiman (incluindo todas as verificações de nulos relevantes), tenho feito isso:

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

   throw new InvalidOperationException("Node 'Name' not found.");
}
Ari Roth
fonte
6
Uma forma abreviada de não obter um erro para nulos é node.Attributes? ["Name"] ?. Value
brandonstrong
1
Também é verdade, embora a única coisa que vou apontar é que embora você possa fazer isso em uma linha (tornando-o bom para uma atribuição ou algo assim), é um pouco menos flexível em termos de controle quando você lança uma exceção ou de outra forma trata o caso em que o nó não tem atributos.
Ari Roth,
1
Acordado. Qualquer pessoa que usar a forma abreviada deve sempre se certificar de que ela não causará problemas posteriores.
brandonstrong,
17

você pode percorrer todos os atributos como faz com os nós

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

    foreach (XmlAttribute att in item.Attributes)
    {
        // attribute stuff
    }
}
Balexandre
fonte
isso será mais preferível .. :)
SHEKHAR SHETE
4

se tudo o que você precisa são os nomes, use xpath. Não há necessidade de fazer a iteração e verificar se há nulo.

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");
um phu
fonte
Os métodos acima não funcionaram com meu XML (embora eu desejasse que funcionassem). Este método sim! Obrigado!
Frecklefoot
4

Se você usar chldNodecomo em XmlElementvez de XmlNode, você pode usar

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

O valor de retorno será apenas uma string vazia , caso o nome do atributo não exista.

Portanto, seu loop pode ser assim:

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

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

Isso selecionará todos os nós <node>circundados por <Node><N0de></N0de><Node>tags e, subsequentemente, fará um loop por eles e lerá o atributo "Nome".

Marco7757
fonte
3

Usar

item.Attributes["Name"].Value;

para obter o valor.

Rahul
fonte
1

Você também pode usar isso;

string employeeName = chldNode.Attributes().ElementAt(0).Name
cela
fonte
1

Mais uma solução:

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

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

Também evita a exceção quando o atributo esperado attributeNamerealmente não existe.

TaW
fonte