tags:

views:

899

answers:

3

I'm struggling with the BizTalk xpath functionality
- the message I'm getting has a blank default namespace
- in C# I'd add a NameSpaceManager
- but I can't see how I can do this in a BizTalk Expression ?

All I'm failing to do is get the values of the HasErrors and NumberOfErrors

<?xml version="1.0" encoding="utf-8"?>
<ImportIndexDocumentResponse   
      xmlns:xsd="http://www.w3.org/2001/XMLSchema"        
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns="http://www.aniteps.com/xml/schemas/awm/images4"&gt;
  <HasErrors>false</HasErrors>
  <NumberOfErrors xsi:type="xsd:int">0</NumberOfErrors>
  <ErrorDescription xsi:type="xsd:string">No exception ocurred.</ErrorDescription>
  ...
+1  A: 

Not great from a performance point of view, but you could use a trick like:

//*[local-name()='HasErrors']

EDIT: The solution is based on the fact that once a message has been correlated, you can be certain that the XML you receive conforms to a known schema, and therefore (as in the XML example in the question) it IS safe to make this assumption. If I recall correctly even the Biztalk mapper uses this same trick, so it is correct in this scenario.

Chris Ballard
Cool, I'll give it a go ... glad to say, performance isn't an issue
SteveC
This is not a correct solution. The proposed XPath expression will select not only the wanted nodes, but any element with the same local-name, regardless of the namespace it belongs to, such as: OhMy:HasErrors, Different:HasErrors , UnWanted:HasErrors, ... etc.
Dimitre Novatchev
I disagree - if you were working with input data whose schema was unknown, then yes you need to check the namespace as well, but almost certainly not needed in this instance.
Chris Ballard
Regardless whether you disagree or not, *the facts* are that your solution can select unexpected and unwanted elements, as you yourself admit in your comment, while at the same time the solution that uses the functions name() and namspace-uri() will always select just the wanted elements.
Dimitre Novatchev
+1  A: 

The answer using local-name() is wrong as it allows unwanted elements to be selected, such as:

  • OhMy:HasErrors
  • Different:HasErrors
  • UnWanted:HasErrors


Here is one correct solution:

In case it is not possible to bind a prefix to the default namespace "http://www.aniteps.com/xml/schemas/awm/images4", one can use the standard XPath function namespace-uri() to specify that the element must reside in a given namespace.

Thereforere, one example of XPath expressions that select the wanted two kind of nodes is:

/*/*[namespace-uri() = 'http://www.aniteps.com/xml/schemas/awm/images4'
   and
     name() = 'HasErrors'
    ]

and the expression:

/*/*[namespace-uri() = 'http://www.aniteps.com/xml/schemas/awm/images4'
   and
     name() = 'NumberOfErrors'
    ]
Dimitre Novatchev
A: 

If your elements are not repeating you could promote them from the response schema as distinguished fields. Then you do not have to worry about coding. Just use:

x = YourMessageName.HasErrors;

If it is a web/wcf reference, you can promote values from the reference.xsd (or xyz.xsd with "Consume Wcf Service Wizard"). Just be aware of that if you update the reference they will "disappear".

Martin Bring
Unfortunately there is no Reference.xsd generated for the web service I'm using ... I believe this is because it's only returning simple types, in this case a string
SteveC