Por que a Xelement cai ao analisar um arquivo XML com um XMLNS?
-
19-09-2019 - |
Pergunta
Então, estou tentando analisar um arquivo XML:
<?xml version="1.0" encoding="utf-8" ?>
<Root>
<att1 name="bob" age="unspecified" xmlns="http://foo.co.uk/nan">
</att1>
</Root>
Usando o seguinte 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 foi escrito no console, a menos que eu exclua xmlns = "http://foo.co.uk/nan" do arquivo XML, após o que, recebo uma lista de nomes e valores de atributos como seria de esperar e, como preciso !
Editar: formatação.
Solução
Você precisa usar o mesmo espaço para nome em seu 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);
}
Atributos não pegam o padrão (xmlns=....
) espaço para nome, para que você não precise qualificá -los. A tag de namespace (xmln:tags=....
) é puramente local para o uso do documento ou da API, os nomes são realmente o nome do nome + nome local sempre, para que você sempre especifique o espaço para nome.
Outras dicas
Sua chamada para Descendentes está consultando um elemento chamado "att1" em nenhum espaço para nome.
Se você ligou Descendants("{http://foo.co.uk/nan}att1")
Você selecionaria o elemento namespaced, mas não o elemento não especificado.
Você pode selecionar elementos chamados "att1" em um ou nenhum espaço para nome como este:
var query = from c in xDoc.Descendants() where c.Name.LocalName == "att1" select c.Attributes;
Você precisa especificar o espaço para nome no Descendants
Ligue assim:
XNamespace ns = "http://foo.co.uk/nan";
foreach (XAttribute a in xDoc.Descendants(ns + "att1"))
{
Console.WriteLine("{0}, {1}",a.Name,a.Value);
}