【问题标题】:Linq to XML query joining parent-child listsLinq to XML 查询加入父子列表
【发布时间】:2010-11-29 20:46:21
【问题描述】:

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

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

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

类动作{
公共字符串 ActionName;
公开名单&lt;Category>分类;
}

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

我完全迷路了,请帮忙。

【问题讨论】:

    标签: linq-to-xml


    【解决方案1】:

    您可以先创建一个 List 来存储唯一的 Category 对象,然后在创建 Action 对象时引用这些对象。 示例 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();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多