我是使用LINQ的新手,并试图从我已转换的XML文档中选择一个节点。XPathSelectElements总是返回表达式必须评估为节点集
这里是原始代码:
// create a LINQ xml doc
XDocument xdoc = XDocument.Parse(xTransformedDoc.OuterXml);
// get sibling elements to the shredding element
IEnumerable<XElement> xe = xdoc.Root.XPathSelectElements("//" + settings.ShredNode + "[1]/(following-sibling|preceding-sibling)[name() != '" + settings.ShredNode + "']");
注:在前面的代码settings.ShredNode被设置为“DocRouteDetail”
起初我还以为是与中的XPath的复杂性问题我使用的语句,但是我已经尝试过每一个组合我能想到的,甚至在与调试滚回来绝对基础:
xdoc.Root.XPathSelectElements(".")
xdoc.Root.XPathSelectElements("//DocRouteDetail")
etc
在所有情况下
它返回NUL l并且它会生成一个异常,返回“Expression必须评估为节点集”。
这发生在C#中的.NET Framework 4.0中。
我已经检查和xdoc.Root变量不为空,我的XML如下所示(瘦身出于安全考虑整个文档):
<DocFWImport xmlns:dtfn2="urn:my-scripts2">
<Header SendDateTime="2014-04-03T19:26:50" />
<Request>
<DocRouteDetail MessagePurpose="1002" ResourceKey="A" >
<DocStop StopNumber="0" Type="0" LocationType="DEPOT">
</DocStop>
<DocStop StopNumber="1" Type="3" LocationType="CUSTOMER" >
</DocStop>
<DocStop StopNumber="2" Type="0" LocationType="DEPOT">
</DocStop>
</DocRouteDetail>
<parmRouteTemplateKey>TEAM</parmRouteTemplateKey>
<DocRouteDetail MessagePurpose="1002" ResourceKey="B" >
<DocStop StopNumber="0" Type="0" LocationType="DEPOT">
</DocStop>
<DocStop StopNumber="1" Type="3" LocationType="CUSTOMER" >
</DocStop>
<DocStop StopNumber="2" Type="0" LocationType="DEPOT">
</DocStop>
</DocRouteDetail>
<parmRouteTemplateKey>SINGLE</parmRouteTemplateKey>
etc
</Request>
</DocFWImport>
它应该返回2个parmRouteTemplateKey元素。
嘿pjotr,谢谢,这确实选择。在阅读你的文章后,我注意到我的前面的后面的语句是无效的......我忘了:: node(),你的例子确实解决了这个问题。不知道为什么我在试图使用以下/之前,当我可以再次回到孩子。 – Justin
我遇到了这个解决方案的一个新问题,然而,当我尝试使用以下代码创建不同元素名称的列表时,selectelements可行: 列表 elToConsider = xe .GroupBy(el => el.Name.ToString ()) .Select(grp => grp.First()。Name.ToString()) .ToList (); 我收到一个xpath异常: XPath表达式评估为意外的类型System.Xml.Linq.XText。 –
Justin
这个标准实际上并没有工作,在重写我的select distinct后,我发现它实际上是将“TEAM”作为选定元素而不是节点(parmRouteTemplateKey)返回。我也将它从*改为node()xdoc.Root.XPathSelectElement(“//”+ settings.ShredNode +“[1]/parent :: node()// child :: node()[name()!= '“+ settings.ShredNode +”'而不是(text())]“); – Justin