XPathSelectElements 始终返回 Expression 必须计算到节点集
本文关键字:计算 节点 点集 返回 Expression XPathSelectElements | 更新日期: 2023-09-27 17:56:33
我是使用 LINQ 的新手,正在尝试从已转换的 XML 文档中选择一个节点。
这是原始代码:
// 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 + "']");
注意:在前面的代码设置中。ShredNode 设置为 "DocRouteDetail"
起初,我认为这是我使用的 xPath 语句的复杂性问题,但是我已经尝试了我能想到的所有组合,甚至在 VS 调试器中将其回滚到绝对基础:
xdoc.Root.XPathSelectElements(".")
xdoc.Root.XPathSelectElements("//DocRouteDetail")
etc
在所有情况下,它都返回 null 并生成一个异常,返回"表达式必须计算到节点集"。
这发生在 C# 的 .NET Framework 4.0 中。
我已经检查了和 XDOC。根变量不为空,我的 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 元素。
这不是XPathSelectElements
的错,您的 XPath 查询无效 - 即带有 |
运算符的部分。您提到的其他基本查询确实有效。如果他们真的没有,那么您发布的代码之外还有其他错误。
我会把它写成
//DocRouteDetail[1]/parent::*/child::*[name()!='DocRouteDetail']
这样它就可以选择您需要的内容。
正如@pjotr所指出的,您的 XPath 尝试无效。您可以尝试使用联合运算符 (|
) 组合 2 个 XPath,如下所示:
var xpath1 = "//" + settings.ShredNode
+ "[1]/following-sibling[name() != '" + settings.ShredNode + "']";
var xpath2 = "//" + settings.ShredNode
+ "[1]/preceding-sibling[name() != '" + settings.ShredNode + "']";
IEnumerable<XElement> xe =
xdoc.Root
.XPathSelectElements(xpath1 + " | " + xpath2);