3

私が取り組んでいるアプリケーションでは、XML ファイルからデータを表示する必要があります。いくつかの変換が行われていますが、最終的には最終結果がツリービューに表示されます。ユーザーがノードをクリックすると、リストビューに詳細がポップアップ表示されます。

ノードが選択されていない場合は、基本的に LINQ を使用して、最初に遭遇したアイテムの詳細を取得します。

これが私のXMLの簡略版です

<root>
   <parent label="parent1">
      <child label="child1">
         <element1>data</element1>
         <element2>data</element2>
         ...
      </child>
      <child label="child2">
         <element1>data</element1>
         <element2>data</element2>
         ...
      </child>
   </parent>
</root>

そして、これを取得するために使用されるコードは次のとおりです (ツリービューが XPathSelectStatement によって設定された親ノードを選択した後):

protected void listsSource_Selecting(object sender, LinqDataSourceSelectEventArgs e)
{
    XElement rootElement = XElement.Load(MapPath(TreeSource.DataFile));
    rootElement = rootElement.XPathSelectElement("//parent[@label='parent1']");
    XElement parentElement;

    parentElement = rootElement;

    var query = (from itemElement in parentElement.Descendants("child")
                 select new
                 {
                     varElement1 = itemElement.Element("element1").Value,
                     varElement2 = itemElement.Element("element2").Value,
                     ...
                 }).Take(1);

    e.result = Query;
}

varElement1これはうまく機能し、そこからとのvarElement2値を読み取ることができます。しかし、ユーザーが実際にノードを選択したときの同様のメカニズムを実装しようとすると、壁にぶつかるようです。

私のアプローチはXPatchSelectStatement、実際のノードに到達するために別のものを使用することでした:

parentElement = rootElement.XPathSelectElement("//child[@label='" + tvwChildren.SelectedNode.Text + "']");

しかし、子ノードの下にネストされたすべての要素を読み取るように構築された適切な LINQ クエリを取得する方法について、私はちょっと困惑しています。を使用してみparentElement.Elements()ましたが、エラーが発生しました。の使用も検討しましNodes()たが、同様の結果が得られました。

ノードにアクセスするために foreach ループを使用できると思いますが、結果を LINQ クエリに取得する方法がわからないため、同じ結果を返すことができますe.Result = query

ご想像のとおり、私はLINQにかなり慣れていないので、ヒントをいただければ幸いです。

4

4 に答える 4

1

child子要素を提供するクエリは次のとおりです (指定されたラベルを持つ要素が1 つしかない場合)。

var childElement = rootNode.Descendants("child")
                           .Single(e=>e.Attribute("label").Value == "child1");

複数のchild要素がありlabel="child1"、それらの要素が異なるparent要素の下にある場合は、同じアプローチを使用して最初にparent要素を取得し、次に要素を取得できchildます。

上記があれば、このクエリを使用してelementノードの下のすべてのノードを取得できchildます。

var elements = childElement.Descendants().Select(e=>e.Value);
于 2012-06-13T07:16:22.243 に答える
1

この場合、データバインディングははるかに簡単だと思います。

XDocument doc = XDocument.Load(filePath);
if (doc.Root == null)
{
throw new ApplicationException("invalid data");
}
tvwChildren.Source=doc;

しかし、このようにしたい場合は、次の方法が役立つことを願っています(正確な解決策ではありません)

XElement root = XElement.Load("Employees.xml");
TreeNode rootNode = new TreeNode(root.Name.LocalName);
treeView1.Nodes.Add(rootNode);
    foreach(XElement employee in root.Elements())
           {
            TreeNode employeeNode = new TreeNode("Employee ID :" + employee.Attribute("employeeid").Value);
            rootNode.Nodes.Add(employeeNode);
                 if (employee.HasElements)
                 {
                    foreach(XElement employeechild in employee.Descendants())
                     {
                        TreeNode childNode = new TreeNode(employeechild.Value);
                        employeeNode.Nodes.Add(childNode);
                     }
                 }
            }

また、より良い linq ステートメントを作成するための Resharper ツールを試すことができます。可能なものを示しており、各 for、foreach ループを linq ステートメントに簡単に変換できます。

于 2012-06-13T05:56:14.770 に答える
0

あなたが何をしようとしているのか完全にはわかりませんが、次のように聞こえます。

var data =
    from p in xml.Root.Elements("parent")
    where p.Attribute("label").Value == "parent1"
    from c in p.Elements("child")
    where c.Attribute("label").Value == "child2"
    from d in c.Elements()
    select d.Value;

それが役立つかどうか教えてください。

于 2012-06-13T08:39:26.403 に答える
0

この Xml ライブラリを使用すると、XPath を次のように記述できます。

XElement child = rootElement.XPathElement(
    "//parent[@label={0}]/child[@label={1}]", "parent1", "child2");
于 2012-06-13T17:55:12.660 に答える