Linq to XML 查询连接父子列表

发布于 2024-10-05 14:43:35 字数 778 浏览 2 评论 0原文

我有一个包含两个列表的 xml 文件,形成父子关系,如下所示:

<代码><类别>
<类别 id="10000">类别 1
<类别 id="10100">类别 2
<类别 id="10101">类别 3 ...

<代码><操作>
<操作名称=“操作 1”><类别><类别 id=10100/><类别 id=10102/>
<操作名称=“操作2”><类别><类别id=10101/><类别id=10103/>
...

每个操作至少具有主列表中的一个类别。 我试图在查询中使用父类别列表中的名称来扩展每个操作中的类别,因此输出结构将如下所示:

类动作{
公共字符串 ActionName;
公共列表<类别>类别;
}

类别类别{
公共字符串类别名称;
公共 int 类别 ID;
}

迷失了,请帮助。

I have an xml file with two lists, forming parent-child relations, like this:

<Categories>
<Category id="10000">Category 1</Category>
<Category id="10100">Category 2</Category>
<Category id="10101">Category 3</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>

Each Action has at least one category from master list.
I am trying in my query to expand categories in each action with their names from parent category list, so the output structure would be something like this:

class Action {
public string ActionName;
public List<Category> Categories;
}

class Category {
public string CategoryName;
public int CategoryId;
}

I am completely lost, please help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

メ斷腸人バ 2024-10-12 14:43:35

您可以首先创建一个列表来存储唯一的类别对象,然后在创建操作对象时引用。
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();

You could first create a List to store unique Category objects you then reference when creating Action objects.
Example C# code:

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

With the XML sample being

<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>

that sample outputs

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

If you prefer to use the join clause the code could be changed as follows:

    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();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文