【问题标题】:"where" query using linq xml使用 linq xml 的“where”查询
【发布时间】:2009-07-14 12:36:49
【问题描述】:

我的大脑一直在努力弄清楚如何执行 linq xml 查询。

我希望查询返回所有“产品”项目的列表,其中类别/名称 =“第一个类别”在以下 xml 中

<catalog>
  <category>
    <name>First Category</name>
    <order>0</order>
    <product>
      <name>First Product</name>
      <order>0</order>
    </product>
    <product>
      <name>3 Product</name>
      <order>2</order>
    </product>
    <product>
      <name>2 Product</name>
      <order>1</order>
    </product>
  </category>
</catalog>

【问题讨论】:

    标签: c# xml linq


    【解决方案1】:

    像这样:

        XDocument doc = XDocument.Parse(xml);
        var qry = from cat in doc.Root.Elements("category")
                  where (string)cat.Element("name") == "First Category"
                  from prod in cat.Elements("product")
                  select prod;
    

    或者也可以使用匿名类型:

        XDocument doc = XDocument.Parse(xml);
        var qry = from cat in doc.Root.Elements("category")
                  where (string)cat.Element("name") == "First Category"
                  from prod in cat.Elements("product")
                  select new
                  {
                      Name = (string)prod.Element("name"),
                      Order = (int)prod.Element("order")
                  };
        foreach (var prod in qry)
        {
            Console.WriteLine("{0}: {1}", prod.Order, prod.Name);
        }
    

    【讨论】:

    • 似乎只有一个名为 First Categorycategory,所以Single 在这里可能更合适。
    • 我认为可以安全地假设这是来自较大 xml 块的片段,否则过滤本身是多余的。在这种情况下,您无法说出给定名称的类别数量...
    • 在各种 UI 框架中,名字都暗示着唯一性。我可能会想到其他几个例子。无论如何,我认为争论什么是相当主观的问题没有多大意义。
    • 我同意,这主要是猜想。无论如何,OP 都有这两种解决方案,所以他们可以选择任何一个。 :)
    • 如果Element 返回null,我认为显式转换为string 不会抱怨?
    【解决方案2】:

    这是一个例子:

            string xml = @"your XML";
    
            XDocument doc = XDocument.Parse(xml);
    
            var products = from category in doc.Element("catalog").Elements("category")
                           where category.Element("name").Value == "First Category"
                           from product in category.Elements("product")
                           select new
                           {
                               Name = product.Element("name").Value,
                               Order = product.Element("order").Value
                           };
            foreach (var item in products)
            {
                Console.WriteLine("Name: {0} Order: {1}", item.Name, item.Order);
            }
    

    【讨论】:

      【解决方案3】:

      您想在此处使用Single 扩展方法。请尝试以下操作:

      var category = doc.RootNode.Elements("category").Single(
          c => c.Attribute("name").Value == "First Category");
      var products = category.Elements("product");
      

      请注意,这假设您只有一个名为“First Category”的类别。如果您可能有更多,我建议使用 Marc 的解决方案;否则,这应该是更合适/更有效的解决方案。此外,如果任何category 节点没有name 子节点,这将引发异常。否则,它应该完全按照您的意愿行事。

      【讨论】:

      • 现在这让我很困惑。这个答案是完全正确的,因为(IMO 公平)假设 OP 只在寻找一个名为“第一类”的类别......
      • 我同意它应该可以工作(尽管属性的东西可能更简单,如果缺少任何元素/属性,你就有抛出异常的风险);在这里 +1...我不知道为什么,但这个问题的所有原始答案都被否决了。
      • @Marc:干杯。是的,我可能应该为空属性对象添加警告,但如果Name 保证存在......我现在只对 MrTortoise 的回答投了反对票。 (一旦我正确地重新阅读了问题和您的答案,我就将您的投票改为了赞成票!)
      猜你喜欢
      • 2018-08-14
      • 2013-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多