4

我正在使用以下查询返回所有子元素,然后基于子节点我想获取结果。

XElement rootElement = XElement.Load(@"E:\Samples\TestConsole\TestConsoleApp\TestConsoleApp\XMLFile1.xml");
        IEnumerable<XElement> lv1s = from lv1 in rootElement.Descendants("A")
                   where lv1.Attribute("Code").Value.Equals("A001") && lv1.Attribute("Lable").Value.Equals("A001")
                   select (from ltd in lv1.Descendants("A1")
                           where ltd.Attribute("Code").Value.Equals("001")
                           select ltd.Elements()).ToList();

但我仍然有以下错误。

Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<System.Collections.Generic.List<System.Collections.Generic.IEnumerable<System.Xml.Linq.XElement>>>' to 'System.Collections.Generic.IEnumerable<System.Xml.Linq.XElement>'. An explicit conversion exists (are you missing a cast?)

请告诉我。

我想要我的 lv1s["A11"], lv1s["A22"] 的值

下面是我的xml

    <?xml version="1.0" encoding="utf-8" ?>
<Document>
  <A Code="A001" Lable="A001">
    <A1 Code="001">
      <A11>A1</A11>
      <A22>A2</A22>
      <A33>A3</A33>
    </A1>
  </A>
  <A Code="A002" Label="A002">
    <A1 Code="002">
      <A44>A44</A44>
      <A55>A55</A55>
    </A1>
  </A>
</Document>

请告诉我。

另外,我如何在返回列表中将“枚举未产生结果”作为计数 0 处理,因为如果发生此错误,它会给出计数 > 0。

4

2 回答 2

3

查询结果的类型为IEnumerable<List<IEnumerable<XElement>>>。但是您正试图将其分配给IEnumerable<XElement>. 为什么?因为对于每个A元素,您都在选择A1子元素列表。这给了你列表的集合。

您可以使用显式结果类型来解决此问题。即代替IEnumerable<XElement> lv1s使用var lvls。或者使用实际的 lvls 类型:IEnumerable<List<IEnumerable<XElement>>> lvls.

或者如果你想得到IEnumerable<XElement>然后使用SelectMany

IEnumerable<XElement> lv1s = 
    rootElement.Descendants("A")
               .Where(lv1 => (string)lv1.Attribute("Code") == "A001" &&
                             (string)lv1.Attribute("Lable") == "A001")
               .SelectMany(lv1 => lv1.Descendants("A1")
                            .Where(ltd => (string)ltd.Attribute("Code") == "001")
                            .Select(ltd => ltd.Elements());

或者以这种方式重写您的查询:

   IEnumerable<XElement> lv1s =  
         from lv1 in rootElement.Descendants("A")
         where (string)lv1.Attribute("Code") == "A001" &&
               (string)lv1.Attribute("Lable") == "A001"
         from ltd in lv1.Descendants("A1")
         where (string)ltd.Attribute("Code") == "001"
         from e in ltd.Elements()
         select e;

返回以下元素:

  <A11>A1</A11>
  <A22>A2</A22>
  <A33>A3</A33>
于 2013-01-29T18:57:37.687 回答
1

一个建议:不要使用.Value, 转换为string. 另外,如果您的变量在任何情况下都是 anIEnumerable<XElement>而不是 a List<XElement>,您为什么需要ToList

XElement rootElement = XElement.Load(@"E:\Samples\TestConsole\TestConsoleApp\TestConsoleApp\XMLFile1.xml");
IEnumerable<XElement> lv1s = 
    from lv1 in rootElement.Descendants("A")
    where (string)lv1.Attribute("Code") == "A001" && (string)lv1.Attribute("Lable") == "A001"
    select (
        from ltd in lv1.Descendants("A1")
        where (string)ltd.Attribute("Code") == "001"
        select ltd.Elements()
    );

您有一个嵌套的 LINQ 查询,并且您的查询也返回一个IEnumerable<XElement>. 尝试删除嵌套查询,并返回单个元素作为查询的结果(括号只是为了清楚起见而添加):

IEnumerable<XElement> lv1s = (
    from lv1 in rootElement.Descendants("A")
    where (string)lv1.Attribute("Code") == "A001" && (string)lv1.Attribute("Lable") == "A001"
    from ltd in lv1.Descendants("A1")
    where (string)ltd.Attribute("Code") == "001"
    from e in ltd.Elements()
    select e
);

此外,如果您只搜索一层深度,您可以使用Elements代替Descendants

IEnumerable<XElement> lv1s = (
    from lv1 in rootElement.Elements("A")
    where (string)lv1.Attribute("Code") == "A001" && (string)lv1.Attribute("Lable") == "A001"
    from ltd in lv1.Elements("A1")
    where (string)ltd.Attribute("Code") == "001"
    from e in ltd.Elements()
    select e
);

如果您想要的只是这些元素的A1--和-- 而不是A2对象:A3XElement

IEnumerable<string> lv1s = (
    from lv1 in rootElement.Elements("A")
    where (string)lv1.Attribute("Code") == "A001" && (string)lv1.Attribute("Lable") == "A001"
    from ltd in lv1.Elements("A1")
    where (string)ltd.Attribute("Code") == "001"
    from e in ltd.Elements()
    select (string)e
);
于 2013-01-29T18:48:29.000 回答