Yossi Dahan [BizTalk]


Monday, September 25, 2006

Taking in and returning Xml from an extension object in xslt

In most cases, when I'm using extension objects from xsl it is with simple type data passed into the component or retrieved from it.

However, in some cases I need to either pass in or retrieve a full xml fragment.

While in many cases it makes sense to get the information before the map execution and then use BizTalk's ability to map multiple documents to one, in some cases it makes perfect sense to get the information directly from the map.

An good example, I believe, is when you need to perform data enrichment - to get more information based on data from the message.

Of course you could have used xpath queries in an expression shape to extract the bits of information you need to work on to variables, then get the data you need through method and web services calls before the map, and use a many-to-one mapping to merge it all, but wouldn't it be nice if you could simply, from within the xsl, call a .net class, pass the value of, say, an attribute, and get back a node set you could iterate on and transform to your format output?

Well - you can.

All you need to do is write a method that returns the type System.Xml.XPath.XPathNodeIterator.
(You could also take in a parameter of this type if you need to receive an xml node-set to your method.

A quick example of such a method is:

public XPathNodeIterator processXmlNodeSet(XPathNodeIterator nodeSet)
XPathNavigator nav = nodeset.Current;
XPathNodeIterator i = nav.Select("//city");
return i;

Of course this method doesn't do much, but it takes in a node-set, and returns part of it based on an xpath.
Real life implementation of course would be fuller, probably involving creating the output based on database reads or maybe performing some complex manipulation on the input.

If you wanted to create a new node-set (not through selecting nodes in an existing node set) you would need to create an XPathDocument.

XpathDocuments are created from a stream, so you could easily create one from an xml in a file, or simply write your xml to a stream such as a memory stream.

With an XpathDocument you can use the CreateNavigator method to create an XpathNavigator and then use the navigator's select method to select the xml fragment you need and return the XpathNodeIterator you need

One last node - I have only tried this approach using custom xsl from a map and using xsl in a standard .net application. I have not tried using this approach with through the mapper with functoids (as I rarely work that way)


Post a Comment

<< Home