Linq Запрос XML с нестандартными пространствами имен

1

Я пытаюсь выполнить запрос 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, которое должно быть в скобке потомка, не сработало.

  • 0
    Это чувствительно к регистру, поэтому name = (string) x.Element ("person") должно быть name = (string) x.Element ("Person"). То же самое для возраста. Не уверен, что это единственная проблема, но это, безусловно, часть проблемы.
  • 0
    Каково ваше требование? Почему вы не комментируете сообщения, если они не работают для вас?
Теги:
linq

1 ответ

2
Лучший ответ

Основная проблема с вашим кодом, как вы правильно определили, - это пространство имен 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"));
  • 0
    Я узнал что-то новое из вашего поста. Спасибо за великолепный пост.
  • 0
    Спасибо, это сработало очень. Похоже, я должен освежить свой XML.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню