使用命名空间运行xpath查询时出现问题

时间:2010-09-27 13:06:22

标签: xpath

我正在尝试使用xpath表达式在xml文档中选择一个节点集,并定义了不同的命名空间。

xml看起来像这样:

<?POSTEN SND="SE00317644000" REC="5566420989" MSGTYPE="EPIX"?>
<ns:Msg xmlns:ns="http://www.noventus.se/epix1/genericheader.xsd">
  <GenericHeader>
    <SubsysId>1</SubsysId>
    <SubsysType>30003</SubsysType>
    <SendDateTime>2009-08-13T14:28:15</SendDateTime>
  </GenericHeader>
  <m:OrderStatus xmlns:m="http://www.noventus.se/epix1/orderstatus.xsd">
    <Header>
      <OrderSystemId>Soda SE</OrderSystemId>
      <OrderNo>20090811</OrderNo>
      <Status>0</Status>
    </Header>
    <Lines>...

我想只选择“Msg” - 具有“OrderStatus”子节点的节点,因此我想使用以下xpath表达式:/ Msg [count('OrderStatus')&gt; 0]但这不起作用,因为我收到一条错误消息:“需要命名空间管理器或XsltContext。此查询具有前缀,变量或用户定义的函数”。

所以我想我想使用一个如下所示的表达式:/ * [local-name()='Msg'] [count('OrderStatus')&gt; 0]但这似乎不起作用..任何想法?

BR,

安德烈亚斯

1 个答案:

答案 0 :(得分:10)

  
    

我想使用以下xpath     表达:

  
/Msg[count('OrderStatus')[ 0]
     
    

但是这不起作用,因为我收到一条错误消息:“命名空间     需要经理或XsltContext。

  

这是常见问题解答。

在XPath中,一个没有前缀的名称始终被认为属于“无命名空间”。

但是,您要选择的元素实际上位于"http://www.noventus.se/epix1/genericheader.xsd" 命名空间。

您有两种可能的方法来编写XPath表达式

  1. 使用托管语言的功能将前缀关联到表达式中名称所属的所有不同名称空间。你还没有说明这个具体案例中的托管语言是什么,所以我无法帮你解决这个问题。可以找到一个C#示例 here
  2. 如果您已将前缀"xxx"与名称空间"http://www.noventus.se/epix1/genericheader.xsd"和前缀"yyy"关联到名称空间"http://www.noventus.se/epix1/orderstatus.xsd",那么您的表达式可以写为:

    /xxx:Msg[yyy:OrderStatus]

    :2:如果您根本不想使用任何前缀,仍然可以构造XPath表达式,但它不会太可读:

    /*[local-name() = 'Msg' and *[local-name() = 'OrderStatus']]

    最后,请注意

    1. 为了测试元素x是否有孩子y,没有必要测试肯定的count(y)只需使用x[y]

    2. Xpath位置从1开始。这意味着NodeSetExpression[0]从不选择节点。您想:NodeSetExpression[1]