Запрос Linq to XML, объединяющий родительско-дочерние списки - PullRequest
0 голосов
/ 29 ноября 2010

У меня есть XML-файл с двумя списками, которые образуют отношения родитель-потомок, например:

<Categories><br> <Category id="10000">Category 1</Category><br> <Category id="10100">Category 2</Category><br> <Category id="10101">Category 3</Category> ...<br> </Categories>

<Actions><br> <Action name="Action 1"><Categories><Category id="10100"/><Category id="10102"/></Categories></Action><br> <Action name="Action 2"><Categories><Category id="10101"/><Category id="10103"/></Categories></Action><br> ...<br> </Actions>

Каждое действие имеет хотя бы одну категорию из основного списка. В своем запросе я пытаюсь расширить категории в каждом действии с помощью их имен из списка родительских категорий, поэтому структура вывода будет выглядеть примерно так:

Действие класса {
открытая строка ActionName;
общедоступный список <Category> Категории;
}

Категория класса {
открытая строка CategoryName;
public int CategoryId;
}

Я полностью потерян, пожалуйста, помогите.

1 Ответ

0 голосов
/ 29 ноября 2010

Сначала можно создать список для хранения уникальных объектов категории, на которые вы затем ссылаетесь при создании объектов действия. Пример кода C #:

    XDocument doc = XDocument.Load(@"..\..\XMLFile1.xml");
    List<Category> referencedCategories =
        (from cat in doc.Root.Element("Categories").Elements("Category")
         where doc.Root.Element("Actions").Elements("Action").Elements("Categories").Elements("Category").Any(c2 => cat.Attribute("id").Value == c2.Attribute("id").Value)
         select new Category()
         {
             CategoryId = (int)cat.Attribute("id"),
             CategoryName = (string)cat
         }).ToList();

    List<Action> actions =
        (from action in doc.Root.Element("Actions").Elements("Action")
         select new Action()
         {
             ActionName = (string)action.Attribute("name"),
             Categories = (from cat in referencedCategories
                           where action.Element("Categories").Elements("Category").Any(cat2 => (int)cat2.Attribute("id") == cat.CategoryId)
                           select cat).ToList()
         }).ToList();

    foreach (Action action in actions)
    {
        Console.WriteLine("Action {0}:", action.ActionName);
        foreach (Category cat in action.Categories)
        {
            Console.WriteLine("\tId: {0}; Name: {1}", cat.CategoryId, cat.CategoryName);
        }
        Console.WriteLine();
    }

Пример XML

<Root>
  <Categories>
    <Category id="10000">Category 1</Category>
    <Category id="10100">Category 2</Category>
    <Category id="10101">Category 3</Category>
    <Category id="10102">Category 4</Category>
    <Category id="10103">Category 5</Category>
  </Categories>

  <Actions>
    <Action name="Action 1">
      <Categories>
        <Category id="10100"/>
        <Category id="10102"/>
      </Categories>
    </Action>
    <Action name="Action 2">
      <Categories>
        <Category id="10101"/>
        <Category id="10103"/>
      </Categories>
    </Action>
  </Actions>

</Root>

этот пример выводит

Action Action 1:
        Id: 10100; Name: Category 2
        Id: 10102; Name: Category 4

Action Action 2:
        Id: 10101; Name: Category 3
        Id: 10103; Name: Category 5

Если вы предпочитаете использовать предложение join, код можно изменить следующим образом:

    XDocument doc = XDocument.Load(@"..\..\XMLFile1.xml");
    List<Category> referencedCategories =
        (from cat in doc.Root.Element("Categories").Elements("Category")
         join cat2 in doc.Root.Element("Actions").Elements("Action").Elements("Categories").Elements("Category") on cat.Attribute("id").Value equals cat2.Attribute("id").Value
         select new Category()
         {
             CategoryId = (int)cat.Attribute("id"),
             CategoryName = (string)cat
         }).ToList();

    List<Action> actions =
        (from action in doc.Root.Element("Actions").Elements("Action")
         select new Action()
         {
             ActionName = (string)action.Attribute("name"),
             Categories = (from cat in referencedCategories
                           join cat2 in action.Element("Categories").Elements("Category") on cat.CategoryId equals (int)cat2.Attribute("id") 
                           select cat).ToList()
         }).ToList();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...