Почему XElement падает при разборе xml-файла с xmlns? - PullRequest
1 голос
/ 11 марта 2010

Итак, я пытаюсь проанализировать XML-файл:

 <?xml version="1.0" encoding="utf-8" ?>
<Root>    
  <att1 name="bob" age="unspecified" xmlns="http://foo.co.uk/nan">    
  </att1>    
</Root>

Используя следующий код:

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);
}

В консоль ничего не записывается, если я не удаляю xmlns = "http://foo.co.uk/nan" из файла xml, после чего я получаю список имен и значений атрибутов, как и следовало ожидать, и по мере необходимости!

Редактировать: Форматирование.

Ответы [ 3 ]

3 голосов
/ 11 марта 2010

Вы должны использовать то же пространство имен в вашем коде:

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);
}

Атрибуты не выбирают пространство имен по умолчанию (xmlns=....), поэтому вам не нужно их квалифицировать. Тег пространства имен (xmln:tags=....) является исключительно локальным для документа или использования API, имена действительно являются пространством имен + локальным именем, поэтому вам всегда нужно указывать пространство имен.

2 голосов
/ 11 марта 2010

Ваш вызов Потомки запрашивает элемент с именем "att1" в пространстве имен.

Если бы вы позвонили Descendants("{http://foo.co.uk/nan}att1"), вы бы выбрали элемент пространства имен, но не элемент без пространства имен.

Вы можете выбрать элементы с именем "att1" в любом пространстве имен или без него, например:

var query = from c in xDoc.Descendants() where c.Name.LocalName == "att1" select c.Attributes;
1 голос
/ 11 марта 2010

Вам необходимо указать пространство имен в вызове Descendants, например:

XNamespace ns = "http://foo.co.uk/nan";
foreach (XAttribute a in xDoc.Descendants(ns + "att1"))
{
    Console.WriteLine("{0}, {1}",a.Name,a.Value);
}
...