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 始终返回 Expression 必须计算到节点集

这不是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);