Почему простой XPATH не работает - PullRequest
4 голосов
/ 14 сентября 2011

У меня есть XML (в BizTalk), который выглядит как

<ns0:Provide xmlns:ns0="http1" xmlns:ns1="http2" xmlns:ns2="http://schemas.microsoft.com/2003/10/Serialization/">
  <ns0:providerRequest>
    <ns1:Header>
      <ns1:Operation>Get_RU_PatchData</ns1:Operation>
      <ns1:RequestId>f6bbeb27-1bfd-4d9c-90e4-d195baf8ca60</ns1:RequestId>
      <ns1:SendDate>2004-02-14T21:44:14</ns1:SendDate>
      <ns1:SenderSystemName>temperat iras</ns1:SenderSystemName>
    </ns1:Header>
    <ns1:Parameters>
      <ns1:Parameter>
        <ns1:Name>turbine corripuit</ns1:Name>
        <ns1:Value>regemque dedit</ns1:Value>
      </ns1:Parameter>
   </ns1:Parameters>
  </ns0:providerRequest>
</ns0:Provide>

Я пытаюсь получить значение единственного параметра в параметрах.Вопрос в том, почему такое утверждение

string(/*[local-name()='Provide' and namespace-uri()='http1']/*[local-name()='providerRequest' and namespace-uri()='http1']/*[local-name()='Parameters' and namespace-uri()='http2'][1]/*[local-name()='Parameter' and namespace-uri()='http2']/*[local-name()='Name'])

работает нормально, а это

string(/Provide/providerRequest/Parameters[1]/Parameter/Name)

ничего не дает?Есть ли способ не создавать такие чудовищные утверждения с пространствами имен?

Ответы [ 5 ]

2 голосов
/ 14 сентября 2011

В зависимости от вашей реализации XPath вы можете зарегистрировать пространства имен XML с помощью ярлыков, чтобы вы могли написать выражение XPath таким образом (учитывая, что вы зарегистрировали http1 как h1 и http2 как h2.

string(/h1:Provide/h1:providerRequest/h2:Parameters[1]/h2:Parameter/h2:Name)
1 голос
/ 15 сентября 2011

Мне нравится помещать все мои константы, включая XPath, в статический класс, а затем ссылаться на него в моем проекте BizTalk.Это имеет ряд преимуществ, в том числе:

  1. Упрощает модульное тестирование и редактирование этих констант;
  2. Это делает формы выражений короче и легче для чтения.

Это не решает проблему длинных XPath, хотя вы всегда можете использовать String.Format(), чтобы сделать их более читабельными,Тем не менее, он имеет преимущества, описанные выше ...

1 голос
/ 14 сентября 2011

Просто объявите пространства имен в документе XSLT, и тогда вы сможете использовать:

string(/ns0:Provide/ns0:providerRequest/ns1:Parameters[1]/ns1:Parameter/ns1:Name)

Просто просматривая локальные имена, вы фактически полностью игнорируете пространства имен - почему вы добавили их впервое место тогда?

0 голосов
/ 03 января 2014

Нет ничего особенного в том, как BizTalk использует Xpath, чем, например, .Net или Java синтаксические анализаторы - как только в документе xml используются пространства имен, вам нужно будет указывать пространство имен (или псевдоним) при создании ссылочных элементов.

Biztalk обходит необходимость в XmlNamespaceManager , используя независимый от пространства имен xpath , который, как вы заметили, довольно многословен (но опять же, он генерируется и обычно скрыт зрение).

Если вы уверены, что имена элементов уникальны в вашем xml, вы можете удалить бит namespace-uri() из ваших путей, т.е.

string(/*[local-name()='Provide']/*[local-name()='providerRequest']
       /*[local-name()='Parameters'][1]/*[local-name()='Parameter']
       /*[local-name()='Name'])

И если вы действительно уверены относительно уникальности имен ваших элементов, вы можете замкнуть путь:

string(//*[local-name()='SomeUniqueElementName']

Но будьте осторожны - для больших XML-документов я столкнулся с проблемами производительности при использовании двойной косой навигации xpath.

0 голосов
/ 05 сентября 2013

Я знаю, что это было какое-то время, но для меня сработало НЕ ссылаться на корневой узел (который содержит пространства имен) в вашем xpath, тогда он работает чисто (например, // Параметр [1]).Но, похоже, у вас есть пространства имен на каждом узле, поэтому, если возможно не квалифицировать все узлы, кроме корневого в вашей схеме, это поможет.Есть что-то в смешивании пространств имен в xpath, которое BizTalk не любит.Надеюсь, это кому-нибудь поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...