Yossi Dahan [BizTalk]


Tuesday, September 12, 2006

Returning text only from xpath in an orchestration

This is another one of those things I simply keep forgetting.

Using the built-in xpath function in an expression shape is extremely useful for extracting and updating information in messages.

However, it seems that this function is much less forgiving when it comes to the xpath you use.

One example of this I bumped into (again) today is that if I have an xml like this:

<ns0:MyRoot xmlns:ns0='MyNamespace>
<ns0:MyElement>free text here</ns0:MyElement>

And I try to extract the text inside a node an xpath like this -

/*[local-name()='MyRoot' and namespace-uri()='MyNamespace']/*[local-name()='MyElement' and namespace-uri()='MyNamespace']

Or even

/*[local-name()='MyRoot' and namespace-uri()='MyNamespace']/*[local-name()='MyElement' and namespace-uri()='MyNamespace']/text()

While both work nicely in almost every xsl engine, BizTalk orchestration's xpath resolves both to empty strings. To get the text contents of the element you have to use xslt's string function -

/*[local-name()='MyRoot' and namespace-uri()='MyNamespace']/*[local-name()='MyElement' and namespace-uri()='MyNamespace']/text())


  • I think is has to be (lowercase s) string(
    /*[local-name()='MyRoot' and namespace-uri()='MyNamespace']/*[local-name()='MyElement' and namespace-uri()='MyNamespace']/text()). Otherwise you'll end up with a Namespace Manager or XslContext needed etc, etc ... error message.

    By Blogger Richard Hallgren, at 19/07/2007, 14:51  

  • Thanks Richard, I think you're right and believe the mistake was cause by an editor's auo-formatting changing the case of the first letter in a sentence (and, of course, me not spotting it).

    I'll update the post.

    By Blogger Yossi Dahan, at 25/07/2007, 08:53  

  • What is wrong with this? I copied the xpath from a node in the xsd and added /text and string() but i get a blank value. I dumped the message to a text file to make sure there is data at the node.

    System.Convert.ToString(xpath(F4006zSingle_Insert_Request, "string(/*[local-name()='RequestF4006zInsert' and namespace-uri()='http://XYZ.OrderIntegration/F4006zInsert']/*[local-name()='sync' and namespace-uri()='']/*[local-name()='after' and namespace-uri()='']/*[local-name()='OrderIntegration.F4006Z' and namespace-uri()='']/@*[local-name()='OYEDOC' and namespace-uri()='']/text())"))

    By Anonymous Anonymous, at 08/08/2007, 20:41  

  • i cann't spot anything obvious from your example (although I'm not sure you need the /text() in the end for attributes, in fact - in most cases you don't need to worry about namespaces at all, as attributes don't inherit namespaces so you often can simply use @myAttribute in xpaths).

    Have you checked the xpath carefully against your message? (I usually just lift it to VS and debug it in a temp xsl file, but you can use xpathmania addon for VS or any other xpath tool)

    By Blogger Yossi Dahan, at 09/08/2007, 20:07  

  • Thank you very much! Yes the attributes dont need text().

    By Anonymous Anonymous, at 13/08/2007, 16:37  

  • i have a similar problem, i have a value that is stored in a node, not an attribute and i can't return the value. here is my xpath function :
    xPathIAU = xpath(Message_IAU_XML, "string(/*[local-name()='InventoryActualUsage' and namespace-uri()='https://kevin4.biztalk.com']/*[local-name()='Header' and namespace-uri()='https://kevin4.biztalk.com']/*[local-name()='To' and namespace-uri()='https://kevin4.biztalk.com']/*[local-name()='PartnerInformation' and namespace-uri()='https://kevin4.biztalk.com']/*[local-name()='PartnerIdentifier' and namespace-uri()='https://kevin4.biztalk.com']/text())");

    any suggestions?

    By Anonymous Anonymous, at 09/06/2008, 20:43  

  • Not really - hard to tell from here :-)

    Presumably you have checked your xpath against the same xml in a different environment (xsl debugging in VS for example) to prove you have not missed anything?

    By Blogger Yossi Dahan, at 09/06/2008, 21:20  

  • Look at my xpath its working fine. I think it may help you

    strPayloadDocType = xpath(XMLDocType,"string(/*[local-name()='Root' and namespace-uri()='http://PartnerRe.BizTalk.CwsDocType']/*[local-name()='PayloadDocType' and namespace-uri()='http://PartnerRe.BizTalk.CwsDocType']/text())");

    By Anonymous Anonymous, at 17/07/2008, 08:16  

  • how do i get the text for an element if i have an array of line items in my message.

    /*[local-name()='MyRoot' and namespace-uri()='MyNamespace']/*[local-name()='MyElement' and namespace-uri()='MyNamespace'][1]/text()) didn't work.

    By Anonymous Anonymous, at 27/05/2009, 19:17  

  • Off the top of my head I can't see anything wrong with your example.
    If you wish - email me an xml instance and I'll have a look

    By Blogger Yossi Dahan, at 27/05/2009, 21:02  

  • Hi, I need to to retrieve all specific nodes found in my xml doc using "//myContent" from a transformed flat file inside pipeline. MyContent element is fouynd in each MyParentelement.
    Any idea or piece of code? I am getting so many erros. I am not sure what type is returned when we do something lioke this xpath(inputmessage, string("//mycontent"), how can I print out the outputt
    Thanks in advance

    By Anonymous eliassal, at 23/02/2010, 22:43  

Post a comment

<< Home