对于我正在处理的应用程序,我必须显示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很新,正如您可能已经猜到的那样,所以任何提示都会非常受欢迎。
答案 0 :(得分: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);
}
}
}
您可以尝试使用Resharper工具来创建更好的linq语句。它显示了可能的,您可以轻松地将每个for,foreach循环转换为linq语句。
答案 1 :(得分:1)
这是为您提供子元素的查询(假设只有一个具有指定标签的child
元素):
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);
答案 2 :(得分: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;
如果有帮助,请告诉我。
答案 3 :(得分:0)
使用this Xml library,您可以编写XPath,如:
XElement child = rootElement.XPathElement(
"//parent[@label={0}]/child[@label={1}]", "parent1", "child2");