WSO2 XPATH всегда возвращает ноль

Это моя проблема. Я получаю следующий XML от DS, который имеет триггер события в ESB.

<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>

Почему он всегда возвращает нулевое значение. Если я назначил дату, все работает нормально.

В отчаянном движении я также попробовал:

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

но ничего не работает.

Есть идеи? Спасибо

3 ответа

Решение

(Отказ от ответственности: я не знаком с WSO2, только с XML/XPath.)

Мне кажется, что ваша проблема связана с пространством имен по умолчанию в вашем XML-входе:

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

Это пространство имен по умолчанию применяется не только к messageCollection элемент, но и все его потомки, включая message элемент. Кроме того, даже если он находится в пространстве имен, имя элемента message остается "сообщением" и не является "ns: сообщением".

Кроме того, я не вижу, где вы объявляете или регистрируете пространство имен http://services.core.solution.com/ds/queue, то есть связать его с префиксом ns:, Если нет, связь между префиксом и пространством имен отсутствует.

Чтобы проверить эту гипотезу, попробуйте

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

а также

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

и дайте мне знать, если эти выражения возвращают что-нибудь.


Вышеприведенные выражения на самом деле не учитывают пространства имен, а игнорируют их. Правильный способ иметь дело с пространствами имен - объявить их. Согласно этой странице, возможно, правильный способ зарегистрировать это пространство имен

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

Вы должны связать ns префикс к правильному пространству имен в конфигурации посредника, например:

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

Просто идея, так как это тестируется только с другими настройками, но, возможно, вы можете проверить следующее: Я только что проверил ваш 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> узлы обоих сообщений и последнего / второго сообщения в контейнере сообщений. Чтобы получить только второе сообщение, у меня работал следующий XPath:

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

который выбирает last() сообщение, которое не имеет родительского сообщения. Так что, может быть, вы можете попробовать, если вы получите createdate с откорректированной версией пространства имен

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

так как возможно, что WSO2 XPath ведет себя иначе, чем тестер XPath, который я использовал, который уже получил созданную дату с выражением, упомянутым первым.

Другие вопросы по тегам