mapping a string containing xml in BizTalk

2020-03-30 01:32发布

问题:

I have an xml document with a node that may optionally contain a string of escaped xml. I'd like to be able to transform that content using xsl in a BizTalk map. Any suggestion how?

I've tried:

  • msxsl:node-set(string). This creates a nameless single node with no content.
  • The document() function using a url prefix of 'data:text/xml' as suggested by helderdarocha here.
  • for-each selecting the text() of the node containing the string
  • using xpath() in an orchestration to extract the string then make a multipart message. It won't let me use an xmlDocument message as one of the messages in a multipart message transform.

Do I have to use a C# helper assembly to accomplish this?

回答1:

I have tackled a similar issue in a project, where I have a series of 2 mappings (both native xslt).

The first map will map your input document to an intermediate format. This format has one "any" node (instead of the escaped XML node), where eventually, I put in the unescaped XML. I unescape using a C# extension object.
The C# code could just be a wrapper for System.Web.HttpUtility.HtmlDecode()

In the second mapping, you can map using plain XPath.

Example Input message:

<root>
  <someNode>blabla</someNode>
  <any>&lt;root2&gt;&lt;myValue&gt;escapedXml&lt;/myValue&gt;&lt;/root2&gt;</any>
</root>

Intermediate format:

<root>
  <someNode>blabla</someNode>
  <any>
    <root2>
      <myValue>escapedXml</myValue>
    </root2>
  </any>
</root>

In your second mapping, you could use XPaths like /root/any/root2/myValue/text() without any issue.

Important Note:

If you need to do XSD validation against this intermediate format, this is a good way to do this as well. You would just need to create the appropriate intermediate XSD according to your needs. In my case this was needed, so I had to validate this unescaped format using a receive pipeline execution in an orchestration.