【问题标题】:IEnumerable<XElement> and foreachIEnumerable<XElement> 和 foreach
【发布时间】:2011-05-26 16:19:02
【问题描述】:

我想选择 a 的所有元素

var q = from artikel in xmlSource.Descendants("ART")
    where artikel.Element("ID").Value.Equals("15")
    select artikel.Elements();

 //Does not work
 foreach (var element in q)
 {
    Console.WriteLine("Customer name = {0}", element.Name);
 }

如何输出所有元素?我对迭代器有一些问题。

我现在不知道如何迭代 IEnumerable 使用 foreach 并访问 element.Name 属性。

//*** 附加信息//

示例 XML

<ARTICLE>
  <ART>
    <ID>0020209</ID>
    <EXP>36</EXP>
    <QTY>1</QTY>
    <SMCAT>B</SMCAT>
    <DSCRD>Example Description 1</DSCRD>
    <ARTCOMP>
      <COMPNO>10710</COMPNO>
      <ROLE>H</ROLE>
      <ARTNO1>320059</ARTNO1>
      <ARTNO2>320059</ARTNO2>
    </ARTCOMP>
    <ARTCOMP>
      <COMPNO>10710</COMPNO>
      <ROLE>V</ROLE>
      <ARTNO1>320059</ARTNO1>
      <ARTNO2>320059</ARTNO2>
    </ARTCOMP>
    <ARTBAR>
      <CDTYP>E13</CDTYP>
      <BC>7680202580475</BC>
      <BCSTAT>A</BCSTAT>
    </ARTBAR>
    <ARTPRI>
      <VDAT>2010-12-01T00:00:00+01:00</VDAT>
      <PTYP>PEXF</PTYP>
      <PRICE>30</PRICE>
    </ARTPRI>
  </ART>
  <ART>
    <ID>0020244</ID>
    <EXP>60</EXP>
    <QTY>30</QTY>
    <DSCRD>FERRO GRADUMET Depottabl 30 Stk</DSCRD>
    <ARTCOMP>
      <COMPNO>1836</COMPNO>
      <ROLE>H</ROLE>
      <ARTNO1>685230</ARTNO1>
      <ARTNO2>685230</ARTNO2>
    </ARTCOMP>
    <ARTCOMP>
      <COMPNO>1836</COMPNO>
      <ROLE>V</ROLE>
      <ARTNO1>685230</ARTNO1>
      <ARTNO2>685230</ARTNO2>
    </ARTCOMP>
    <ARTCOMP>
      <COMPNO>5360</COMPNO>
      <ROLE>L</ROLE>
      <ARTNO1>685230</ARTNO1>
      <ARTNO2>685230</ARTNO2>
    </ARTCOMP>
  </ART>
</ARTICLE>

我必须将此 XML 文件导入到规范化的 MySQL 表中。 ARTCOMP / ARTBAR 是 MySQL 数据库中的附加表。

一开始,我想在一个空的 MySQL 表中将所有字段创建为 varchar()。另外一个问题是,并非每个 ART 元素都有相同的子元素。也许有更好的方法来查找所有可能的子元素(一种模式)。

【问题讨论】:

  • 您的foreach 没有问题,更有可能是您的查询没有返回任何元素。尝试在调试器中检查q。它包含什么?
  • @driis:不,给定的代码无法编译。 Name 不是 IEnumerable&lt;XElement&gt; 的属性...

标签: c# linq ienumerable


【解决方案1】:

您的select 子句意味着q 的类型实际上是IEnumerable&lt;IEnumerable&lt;XElement&gt;&gt;。我怀疑你的意思是:

var q = from artikel in xmlSource.Descendants("ART")
        where artikel.Element("ID").Value.Equals("15")
        from element in artikel.Elements()
        select element;

或者:

var q = from artikel in xmlSource.Descendants("ART")
        where (string) artikel.Element("ID") == "15"
        from element in artikel.Elements()
        select element;

甚至:

var q = from artikel in xmlSource.Descendants("ART")
        where (int) artikel.Element("ID") == 15
        from element in artikel.Elements()
        select element;

这将为q 提供一个仅IEnumerable&lt;XElement&gt; 的类型 - 它基本上会使结果变平。您将获得一系列 all 元素,这些元素位于名为“ART”的元素的正下方,而“ART”又具有值为 15 的“ID”元素。

如果这不是您要查找的内容,请提供更多信息 - 最好是示例 XML 文件以及您的预期输出。

您似乎不太可能真的想要打印所有元素的元素名称...客户名称应该作为 存储在某处(文本在元素或属性中),而不是元素名称。

编辑:如果您想要使用IEnumerable&lt;IEnumerable&lt;XElement&gt;&gt;,您可以使用:

foreach (var result in q)
{
    Console.WriteLine("Next result...");
    foreach (var element in result)
    {
        Console.WriteLine("Got name: {0}", element.Name);
    }
}

【讨论】:

  • 注意 (int) artikel.Element("ID") == 15 的使用 - 这是 Xlinq API 的一个非常好的改进:它尝试将 Value 属性强制转换为类型而不需要访问 @987654333 @property 并在不存在时处理异常。此外,您可以强制转换为int?,如果元素不存在,null 将被返回,允许您容忍丢失的节点而无需繁琐的检查。
  • 非常感谢您的回复。正如您在帖子中所说,q 的类型是 IEnumerable>。如果我在调试器中检查变量 q,我会看到很多结果。我的问题是,我不知道如何对每个结果进行迭代。我的目标是找出所有元素的所有名称。对于每个元素名称,我必须在 MySQL 表中创建一个字段。我的问题是,我不知道如何处理 IEnumerable> 并迭代它们。
  • @Brainski:好的,如果你想要它是IEnumerable&lt;IEnumerable&lt;XElement&gt;&gt;,这很容易处理。我会编辑...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多