Why simple XPATH does not work

I have XML (in BizTalk) that looks like

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

I am trying to get the value of a single parameter in parameters. The question is why is a statement like this

 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']) 

works fine while

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

gives nothing? Is there a way to not create such monstrous statements with namespaces?

+4
source share
5 answers

Just declare namespaces in your XSLT document, and then you can use:

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

Just by looking at local names, you actually ignore namespaces - why did you add them in the first place?

+1
source

Depending on your XPath implementation, you can register shortcut XML namespaces so that you can write an XPath expression like this (given that you have registered http1 as h1 and http2 as h2 .

 string(/h1:Provide/h1:providerRequest/h2:Parameters[1]/h2:Parameter/h2:Name) 
+2
source

I like to put all my constants, including XPaths, in a static class, and then reference this in my BizTalk project. This has a number of advantages, including:

  • This facilitates the unit test and edits these constants;
  • This simplifies and simplifies the reading of expressions.

This does not solve the problem of long XPaths, although you can always use String.Format() to make them more readable. However, it has the advantages described above ...

+1
source

I know it has been a while, but what worked for me is NOT to reference the root of the node (which contains namespaces) in your xpath, then it works clean (for example, // Parameter [1]) . But it seems that you have namespaces on each node, so if possible, so as not to qualify all the nodes, but the root in your schema, this will help. There is something mixing up namespaces in xpath that BizTalk doesn't like. Hope this helps someone.

0
source

There is nothing unusual in the way BizTalk uses Xpath than, for example. .Net or Java - as soon as an XML document uses namespaces, you need to specify a namespace (or an alias) when creating link elements.

Biztalk circumvents the need for an XmlNamespaceManager by using the xpath agnostic namespace , which, as you noted, is pretty verbose (but again, it is generated and usually hidden from view).

If you are sure that the element names are unique in your xml, you can clear the namespace-uri() bit from your paths, i.e.

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

And if you are really sure of the uniqueness of the names of your elements, you can short-circuit the path:

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

But be careful - for large xml documents, I ran into performance issues with bidirectional xpath navigation.

0
source

All Articles