我的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
也可能没有任何直接雇员。在这种情况下,单击root应该产生第一个具有员工的经理下的第一个Employee。因此,如果我们假设Employee 4
和Employee 5
不在Manager 1
下,则点击root会产生Employee 3
。
我尝试使用Element
,Elements
,Descendant
和Descendants
的一些不同变体,并且有点卡住了。
我想我可以为每个单独的组合编写方案(即rootClicked
,managerClicked
和employeeClicked
),这就是我原来做的,但我正在寻找代码方面,希望更容易维护的东西。
我非常希望使用root.Element(&#34; Employee&#34;)会有所帮助,但是会引发Could not find an implementation of the query pattern for source type 'System.Xml.Linq.XEelement'. 'select' not found
错误。
有人能够为我提供解决我的问题所需要的那么小的推动吗?
答案 0 :(得分: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]
选择:
一个。单击的节点,如果是“员工”
或者:
湾点击节点的第一个desendant-or-self的第一个子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" />
答案 1 :(得分: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
);