Как получить значение дочернего элемента в XML с помощью LINQ

1

Я пытаюсь получить доступ к значению дочернего элемента в xml.

<Menus>
    <ParentMenu>
        <ParentName>Home</ParentName>
    </ParentMenu>
    <ParentMenu>
        <ParentName>Shop</ParentName>
        <SubMenus>
            <Submenu>
                <SubName>SHop1</SubName>
            </Submenu>
            <Submenu>
                <SubName>SHop2</SubName>
            </Submenu>
            <Submenu>
                <SubName>SHop3</SubName>
            </Submenu>
            <Submenu>
                <SubName>SHop4</SubName>
            </Submenu>
        </SubMenus>
    </ParentMenu>
    <ParentMenu>
        <ParentName>MegaMenu</ParentName>
    </ParentMenu>
</Menus>

Есть мой код

var menus = (from Parent in xdoc.Root.Descendants("ParentMenu")
             select new Menus
             {
                 ParentName = Parent.Descendants("ParentName").First().Value,
                 Submenus = (from sub in Parent.Descendants("SubMenus")
                                               .Descendants("Submenu")
                             select new SubMenus 
                             {
                                 SubName = sub.Descendants("SubName")
                                              .First().Value,
                             }).ToList()
             }).ToList();
  • 0
    Не могли бы вы также опубликовать соответствующий фрагмент Xml, который вы пытаетесь проанализировать?
  • 0
    <Menus> <ParentMenu> <ParentName> Home </ ParentName> </ ParentMenu> <ParentMenu> <ParentName> Магазин </ ParentName> <SubMenus> <Подменю> <SubName> SHop1 </ SubName> </ Submenu> <Подменю> <SubName> SHop2 </ SubName> </ Submenu> <Submenu> <SubName> SHop3 </ SubName> </ Submenu> <Submenu> <SubName> SHop4 </ SubName> </ Submenu> </ SubMenus> </ ParentMenu> <ParentMenu> <ParentName> MegaMenu </ ParentName> </ ParentMenu>
Показать ещё 5 комментариев
Теги:
linq
linq-to-xml

1 ответ

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

Учитывая, что вы просто просто десериализуете всю Xml-структуру, я считаю, что Xel Deserialization - лучшая стратегия для того, что вы пытаетесь:

Учитывая следующие структуры DTO (отмечая также, что элементы ParentMenu не имеют обертки):

public class Submenu
{
    public string SubName { get; set; }
}
public class ParentMenu
{
    public string ParentName { get; set; }
    public List<Submenu> SubMenus { get; set; }
}
public class Menus
{
    [XmlElement("ParentMenu")]
    public List<ParentMenu> ParentMenus { get; set; }
}

Затем вы можете просто десериализовать:

var ser = new XmlSerializer(typeof(Menus));
using (var sr = new StringReader(xml)) // Or use TextReader if you are off file
{
    var result = (Menus)ser.Deserialize(sr);
}

Если, однако, вы действительно хотите выполнить описанную выше десериализацию вручную в Linq в Xml, это будет работать с той же структурой DTO, что и выше:

var menus = (from Parent in xdoc.Root.Descendants("ParentMenu")
             select new ParentMenu
             {
                 ParentName = Parent.Descendants("ParentName").First().Value,
                 SubMenus = (from sub in Parent.Descendants("SubMenus")
                                               .Descendants("Submenu")
                             select new Submenu
                             {
                                 SubName = sub.Descendants("SubName")
                                              .First().Value,
                             }).ToList()
             }).ToList();
  • 0
    но я использую MVC 5 это работает в MVC?
  • 0
    Да, десериализация будет работать и для MVC :) Обновление переименовывает DTO в строке - по соглашению, свойства коллекции должны быть во множественном числе (заканчиваться на «s»), чтобы передать намерение следующему разработчику, читающему код. Когда вы .Select вы проецируете один элемент за раз.
Показать ещё 1 комментарий

Ещё вопросы

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