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, который я использовал, который уже получил созданную дату с выражением, упомянутым первым.