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ます。また、変数がいずれにせよであり、IEnumerable<XElement>ではない場合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
);

また、1レベルの深さのみを検索する場合は、次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 に答える