jim582686

Hello All!

I'm new to BizTalk (and these forums) and am wondering if anyone can help out. I am trying to map an entire XML document (by first converting it to a string) to an attribute in an SQL updategram. I tried using a Mass Copy functoid however it will not allow output to an attribute (not sure it would convert it properly anyway). With the Scripting functoid, I do not seem to have access to the XMLDOM which prohibits me from traversing the nodes and forming my output dynamically.

Can anyone suggest a method I might use that would be resuable

Example XML (input):

< xml version="1.0" encoding="us-ascii" ><Events><Event Type="active"><User>1</User></Event></Events>

Example XML (desired output):

<DBInsert><sync><after>

<myTable myField="< xml version="1.0" encoding="us-ascii" ><Events><Event Type="active"><User>1</User></Event></Events>" />

</after></sync></DBInsert>

Thanks in advance!

Jim



Re: BizTalk R2 General Functoid/mapping question

AlanJamesSmith

Hi Jim,

I've had this mapping problem before, and not hit on a good solution. I've heard that there is a way to solve it in a map (maybe someone will post here).

You cuyld do this in an orchestration by getting the XML of the inbound message as a string, and assigning it to the updategram field:

Add two XmlDcument variables to the orchestration (xmlDocIn and xmlDocOut) and a string variable (stringOut).

In an expression shape, add the code xmlDocIn = InboundMessage

When constructing OutboundMessage, in a message assignemnt add the code:

stringOut = "<DBInsert><sync><after><myTable myField=\"" + xmlDocIn.OuterXml + "\" /></after></sync></DBInsert>";

xmlDocOut = new XmlDocument();

xmlDocOut.LoadXml (stringOut);

OutboundMessage = xmlDocOut;

Another way could be to use a custom send pipelie component:

In the execute method of the component:

Use an XmlStreamReader to read the inbound message stream.

Use an xmlStreamWriter to write out the oubound message stream

Regards,

Alan





Re: BizTalk R2 General Functoid/mapping question

jim

Perfect! Thanks, Alan!





Re: BizTalk R2 General Functoid/mapping question

miguelito928

I really need a solution like this but within the context of a Map on a port. Anyone have any ideas Thanks in advance.



Re: BizTalk R2 General Functoid/mapping question

miguelito928

Ok, here's how I did it...

I put a Scripting Functoid into the map (connecting it to nothing) and configured it to be an "Inline XSLT Call Template" with the following code:

Code Snippet

<xsl:template match="*" mode="toStr">&lt;<xsl:value-of select="name()"/><xsl:apply-templates select="@*" mode="toStr"/>&gt;<xsl:apply-templates mode="toStr"/>&lt;/<xsl:value-of select="name()"/>&gt;</xsl:template>

<xsl:template match="@*" mode="toStr"><xsl:text> </xsl:text><xsl:value-of select="name()"/>="<xsl:value-of select="."/>"</xsl:template>

continued in the next post....





Re: BizTalk R2 General Functoid/mapping question

miguelito928

Then I put in another Scripting Functoid (connecting it to the field, in my case an attribute, on the destination schema that was to hold the string version of the xml) and configured it to be "Inline XSLT" with the following code:

Code Snippet
<xsl:attribute name="jobXml">
<xsl:apply-templates select="." mode="toStr"/>
</xsl:attribute>

And it seems to work pretty good. Hope this helps someone else.




Re: BizTalk R2 General Functoid/mapping question

miguelito928

Actually I just found a problem with the two xsl templates I created. It gets the attributes of nodes but not the namespace declaration. I'll post a fix shortly. Thanks.



Re: BizTalk R2 General Functoid/mapping question

miguelito928

Ok here's the new fixed templates:

Code Snippet

<xsl:template match="*" mode="toStr">
<xsl:text>&lt;</xsl:text>
<xsl:value-of select="name()"/>
<xsl:for-each select="namespace::*[local-name() != 'xml' and not(parent::*[parent::*])]">
<xsl:text> xmlns:</xsl:text>
<xsl:value-of select="name()"/>
<xsl:text>='</xsl:text>
<xsl:value-of select="."/>
<xsl:text>'</xsl:text>
</xsl:for-each>
<xsl:apply-templates select="@*" mode="toStr"/>
<xsl:text>&gt;</xsl:text>

<xsl:apply-templates mode="toStr"/>

<xsl:text>&lt;/</xsl:text>
<xsl:value-of select="name()"/>
<xsl:text>&gt;</xsl:text>
</xsl:template>

<xsl:template match="@*" mode="toStr">
<xsl:text> </xsl:text>
<xsl:value-of select="name()"/>
<xsl:text>='</xsl:text>
<xsl:value-of select="."/>
<xsl:text>'</xsl:text>
</xsl:template>

They seem to work pretty good. Hope this helps.