Я пытаюсь выполнить запрос XML файла, однако на каком-то узле есть пространства имен, другие не приводят к тому, что вы никогда не получите полного решения.
Мне было интересно, можно ли сделать это без Xpath?
XML
<Household name="Home" xmlns="AP:CB" description="Home" >
<InsuranceClaims/>
<mortgages>
<mortgage id="Sally Mae" xmlns="AP:CB" />
</mortgages>
<Appliances>
<Appliance key="Stove" value="5000" />
</Appliances>
<Persons>
<Person name="Henry" age="35" />
<Person name="Jill" age="23" xmlns="AP:CB"/>
</Persons>
</Household>
поэтому у нас есть пространство имен AP: CB, которое существует на некоторых элементах, а не на других.
Мои текущие попытки не дали никакого результата.
_Household = _XDoc.Descendants()
.Where(x => x.Name == "Persons")
.Select(x => new
{
name = (string)x.Element( "Person").Attribute("name").Value,
age = (string)x.Element("Person").Attribute("age").Value
})
.ToDictionary(x => x.age, x => x.name);
Надеюсь, у меня есть общая идея.
edit: обновленная анимация для соответствия чувствительности к регистру, тот же результат. Добавление значения и изменение предложения where, которое должно быть в скобке потомка, не сработало.
Основная проблема с вашим кодом, как вы правильно определили, - это пространство имен XML. Хотя вы ошибаетесь, что некоторые элементы в вашем коде имеют их, а некоторые нет: дочерний узел наследует объявление xmlns
от своего родителя, а это означает, что все элементы в документе находятся в одном пространстве имен.
При использовании LINQ to XML в документах с пространствами имен вы должны явно указать это пространство имен:
XNamespace ns = "AP:CB";
…
_Household = _XDoc.Descendants()
.Where(x => x.Name == ns + "Persons")
.Select(x => new
{
name = (string)x.Element(ns + "Person").Attribute("name").Value,
age = (string)x.Element(ns + "Person").Attribute("age").Value
})
.ToDictionary(x => x.age, x => x.name);
Хотя этот код вернет только одно значение (для Генри), потому что вы выбираете все элементы Persons
и для каждого из них выбираете свой первый дочерний узел Person
.
Вместо этого я напишу запрос следующим образом:
_Household = _XDoc.Descendants(ns + "Persons")
.Elements(ns + "Person")
.ToDictionary(x => (int)x.Attribute("age"), x => (string)x.Attribute("name"));