¿Por qué XElement caída sobre al analizar un archivo XML con una xmlns?
-
19-09-2019 - |
Pregunta
Así que estoy tratando de analizar un archivo XML:
<?xml version="1.0" encoding="utf-8" ?>
<Root>
<att1 name="bob" age="unspecified" xmlns="http://foo.co.uk/nan">
</att1>
</Root>
Usando el siguiente código:
XElement xDoc= XElement.Load(filename);
var query = from c in xDoc.Descendants("att1").Attributes() select c;
foreach (XAttribute a in query)
{
Console.WriteLine("{0}, {1}",a.Name,a.Value);
}
Nada está escrito a la consola a menos elimino xmlns = "http://foo.co.uk/nan" del archivo XML, después de lo cual, me sale una lista de nombres y valores, como cabría esperar de atributos, y ya que necesito!
Editar:. Formateo
Solución
Usted tiene que usar el mismo espacio de nombres en el código:
XElement xDoc= XElement.Load(filename);
XNamespace ns = "http://foo.co.uk/nan";
var query = from c in xDoc.Descendants(ns + "att1").Attributes() select c;
foreach (XAttribute a in query)
{
Console.WriteLine("{0}, {1}",a.Name,a.Value);
}
Los atributos no recogen el espacio de nombres (xmlns=....
) predeterminado, por lo que no es necesario para calificar. La etiqueta de espacio de nombres (xmln:tags=....
) es puramente local al documento o API utilización, los nombres son realmente espacio de nombre + nombre local siempre por lo que tiene que especificar siempre el espacio de nombres.
Otros consejos
Su llamada está consultando a un elemento denominado " ATT1" en ningún espacio de nombres.
Si llamó Descendants("{http://foo.co.uk/nan}att1")
debe seleccionar el elemento de espacio de nombres pero no el espacio de nombres no-elemento.
Se puede seleccionar elementos nombrados "ATT1" en cualquier espacio de nombres o ninguna como esta:
var query = from c in xDoc.Descendants() where c.Name.LocalName == "att1" select c.Attributes;
Es necesario especificar el espacio de nombres en la llamada Descendants
, como esto:
XNamespace ns = "http://foo.co.uk/nan";
foreach (XAttribute a in xDoc.Descendants(ns + "att1"))
{
Console.WriteLine("{0}, {1}",a.Name,a.Value);
}