1

私のXMLファイルは、次のような構造で構成されています。

<root>
    <Manager name="1">
        <Manager name="2">
            <Employee name="3">
        </Manager>
        <Manager name="abe">
        </Manager>
        <Employee name="4">
        <Employee name="5">
    </Manager>
</root>

XMLはツリービューをフィードし、ユーザーがツリービューのどこをクリックしたかに応じて、クリックされた従業員を取得するか(使用できるので簡単ですtreeview.SelectedNode)、そうでない場合は、クリックがルートノードにあった場合、またはマネージャーノード、マネージャーの下の最初の従業員。

つまり

  • をクリックすると、rootの詳細が表示されますEmployee 4(最初の従業員レコードはすぐ下Manager 1にありますroot)。
  • をクリックすると、Manager 1も表示されEmployee 4ます。
  • クリックするとManager 2が表示されEmployee 3ます。
  • クリックManager Abeしても結果は得られません。
  • Employee 5その従業員を直接クリックした場合にのみ表示されます。

Manager 1彼の下に直接の従業員がいない可能性もあります。その場合、ルートをクリックすると、従業員がいる最初のマネージャーの下に最初の従業員が表示されます。したがって、仮定Employee 4し、Employee 5下になかった場合Manager 1、ルートをクリックすると。が生成されEmployee 3ます。

、、、のいくつかの異なるバリアントを使用してみElementましたがElements、少し行き詰まっています。DescendantDescendants

個々の組み合わせ(つまり、、および)ごとにシナリオを作成できると思いますがrootClickedmanagerClickedこれemployeeClickedは私が最初に行ったことですが、コード的に保守しやすいものを探しています。

root.Element( "Employee")を使用すると役立つことを期待していましたが、Could not find an implementation of the query pattern for source type 'System.Xml.Linq.XEelement'. 'select' not foundエラーが発生しました。

誰かが私の問題を解決するために必要なその小さなナッジを私に提供することができますか?

4

2 に答える 2

4

XPathの使用

ClickedNode.XPathEvaluate
    ("self::Employee | self::Manager/Employee[1] | self::root/Manager[1]/Employee[1]")

更新

編集された質問への回答:

使用

 ClickedNode[self::Employee]
|
 ClickedNode[not(self::Employee)]/descendant-or-self::Manager[Employee][1]/Employee[1]

これは次のいずれかを選択します

a。クリックされたノード(「従業員」の場合)

または:

b。Employeeクリックされたノードの最初の子孫または自己の最初の子、つまりマネージャーであり、子がありますEmployee

また、ClickedNodeがXElement(またはXNode)の場合は、次のようにします

  ClickedNode.XPathEvaluate
        (self::*[self::Employee]
      | self::node()[not(self::Employee)]
                       /descendant-or-self::Manager[Employee][1]/Employee[1]
        )

最後に、完全なC#コードを次に示します

TestLinqXpathという名前の静的クラス

using System.Xml.Linq;
using System.Xml.XPath;

namespace TestLinqXpath
{
    public  static class TestLinqXpath
    {
        public static XElement SelectNearestDescendantEmployee(XElement clicked)
        {
            string Expr =
@"(self::*[self::Employee]
 | self::node()[not(self::Employee)]
           /descendant-or-self::Manager[Employee][1]/Employee[1]
   )";
            XElement result = clicked.XPathSelectElement(Expr);

            return result;
        }
    }
}

と広範なテスト

using System;
using System.Xml.Linq;
using System.Xml.XPath;

namespace TestLINQ_Xml
{
    class Program
    {
        static void Main(string[] args)
        {
            Test();
        }

        static void Test()
        {
            string xml = 
@"<root>
    <Manager name='1'>
        <Manager name='2'>
            <Employee name='3'/>
        </Manager>
        <Manager name='abe'>
        </Manager>
        <Employee name='4'/>
        <Employee name='5'/>
    </Manager>
</root>";
            XElement top = XElement.Parse(xml);

            XElement cliked1 = top;
            XElement res1 = TestLinqXpath.TestLinqXpath.SelectNearestDescendantEmployee(cliked1);
            Console.WriteLine(res1.ToString());

            XElement cliked2 = top.XPathSelectElement("Manager[@name='1']");
            XElement res2 = TestLinqXpath.TestLinqXpath.SelectNearestDescendantEmployee(cliked2);
            Console.WriteLine(res2.ToString());

            XElement cliked3 = top.XPathSelectElement(".//Manager[@name='2']");
            XElement res3 = TestLinqXpath.TestLinqXpath.SelectNearestDescendantEmployee(cliked3);
            Console.WriteLine(res3.ToString());

            XElement cliked4 = top.XPathSelectElement(".//Manager[@name='abe']");
            XElement res4 = TestLinqXpath.TestLinqXpath.SelectNearestDescendantEmployee(cliked4);
            Console.WriteLine((res4 != null) ? res4.ToString() : "null");

            XElement cliked5 = top.XPathSelectElement(".//Employee[@name='5']");
            XElement res5 = TestLinqXpath.TestLinqXpath.SelectNearestDescendantEmployee(cliked5);
            Console.WriteLine(res5.ToString());
        }
    }
}

このテストを実行すると、必要な正しい結果が生成されます。

<Employee name="4" />
<Employee name="4" />
<Employee name="3" />
null
<Employee name="5" />
于 2012-10-21T22:03:14.560 に答える
1

このlinq2xmlは実行する必要があります

doc.Descendants("Manager").Where(n=>n.Attribute("name").Value=="yourManagerID")
.Select(
x=>x.Elements("Employee").Count()!=0 
?
x.Elements("Employee").First().Attribute("name").Value
:
x.Elements("Manager").First().Element("Employee").Atrribute("name").Value
);
于 2012-10-21T20:05:14.840 に答える