WSO2 XPATH始终返回null

时间:2014-12-31 00:29:20

标签: xpath wso2 wso2esb soa synapse

这是我的问题。我从具有ESB事件触发器的DS接收以下xml。

<messageCollection xmlns="http://services.core.solution.com/ds/queue">
   <message>
      <messageid>3083e5b9-f8fd-426f-a017-42439f47eefc</messageid>
      <messagetypeid>1</messagetypeid>
      <message>''</message>
      <processed>false</processed>
      <createddate>2014-12-30T14:38:11.782-04:00</createddate>
      <modifieddate>2014-12-30T14:38:11.782-04:00</modifieddate>
      <count>7</count>
   </message>
    <message>
      <messageid>2283e5b9-f8fd-426f-a017-42439f47eefc</messageid>
      <messagetypeid>2</messagetypeid>
      <message>''</message>
      <processed>false</processed>
      <createddate>2014-12-30T14:38:11.782-04:00</createddate>
      <modifieddate>2014-12-30T14:38:11.782-04:00</modifieddate>
      <count>7</count>
   </message>
</messageCollection>

并在有效载荷调解中实施此:

<payloadFactory media-type="xml">
    <format>
        <p:updateLastPollingControl xmlns:p="http://services.core.solution.com/ds/queue">
            <xs:lastpolling xmlns:xs="http://services.core.solution.com/ds/queue">$1</xs:lastpolling>
        </p:updateLastPollingControl>
    </format>
    <args>
        <arg evaluator="xml" expression="//ns:message[last()]/ns:createddate" /> </args>
</payloadFactory>

为什么总是返回null值。如果我对日期进行了编码,一切正常。

在绝望的举动中我也尝试过:

> //ns:message[last()]/ns:createddate/text() 
> /*/ns:message[last()]/ns:createddate   
> //ns:message[last()]/createddate
> /*/message[last()]/createddate

但似乎没有任何效果。

有什么想法吗?感谢

3 个答案:

答案 0 :(得分:2)

(免责声明:我不熟悉WSO2,只使用XML / XPath。)

在我看来,您的问题是由XML输入中的默认命名空间引起的:

<messageCollection xmlns="http://services.core.solution.com/ds/queue">

此默认命名空间不仅适用于messageCollection元素,还适用于其所有后代,包括message元素。此外,即使它在命名空间中,message的元素名称仍为“message”,而不是“ns:message”。

此外,我无法看到您声明或注册名称空间http://services.core.solution.com/ds/queue的位置,即将其与前缀ns:相关联。如果不这样做,则前缀和命名空间之间没有任何关联。

要测试此假设,请尝试

//*:message[last()]/*:createddate

//*[local-name() = 'message'][last()]/*[local-name() = 'createddate']

让我知道这些表达式是否会返回任何内容。


上述表达式并没有真正考虑名称空间,而是忽略了它们。处理命名空间的正确方法是声明它们。根据{{​​3}},注册此命名空间的正确方法可能是

<args>
   <arg evaluator="xml" expression="//ns:message[last()]/ns:createddate" xmlns:ns="http://services.core.solution.com/ds/queue"/>
</args>

答案 1 :(得分:1)

只是一个想法,因为这只是使用不同的设置测试,但也许您可以检查以下内容: 我刚刚在版本

中测试了你的XPath
//*/message[last()]/createddate/text()

结果为2014-12-30T14:38:11.782-04:00

然后我检查了

的结果
//*/message[last()]

不仅返回了最后一条消息,而且返回

<message>''</message>
<message>
  <messageid>2283e5b9-f8fd-426f-a017-42439f47eefc</messageid>
  <messagetypeid>2</messagetypeid>
  <message>''</message>
  <processed>false</processed>
  <createddate>2014-12-30T14:38:11.782-04:00</createddate>
  <modifieddate>2014-12-30T14:38:11.782-04:00</modifieddate>
  <count>7</count>
</message>
<message>''</message>

实际上是所有last()个消息节点 - 两个消息的两个内部<message>''</message>节点以及messagecontainer中的最后/第二个消息。要获取第二条消息,以下XPath为我工作:

//*/message[not(parent::message)][last()]

选择没有父消息的last()消息。因此,如果您使用名称空间调整版

获取createddate,也许可以尝试
//*/message[not(parent::message)][last()]/createddate/text()

因为WSO2 XPath可能与我使用的XPath测试程序不同,后者已经使用首先提到的表达式检索了createddate。

答案 2 :(得分:0)

您需要将ns前缀绑定到介体配置中的右侧命名空间,如下所示:

<arg xmlns:ns="http://services.core.solution.com/ds/queue" ...