A random collection of epiphanies, thoughts and problem solutions pertaining to .NET and BizTalk.

Wednesday, January 19, 2005

Inline XSLT Call Template


Google's Biztalk group posted this interesting problem about how to use the Inline XSLT Call Template and cumulative functoid in the map. I am quoting Jeremy's question here:



"In the following sample, I have a multiple invoice file that has 1 header record and a repeating detail record for each invoice. Can someone help me using inline xslt to sum the detail records of each invoice so that I can get the total for each invoice. I have seen how to do this just using xslt instead of the mapper, but I would like to do this within the mapper as I have other functoids that I am using. It appears I cannot get the cumulative sum functoid to sum each invoice with the scope parameter; instead it always seems to sum the entire file or nothing at all."


inbound:
<Invoices xmlns="http://www.google.com">
<Invoice>
<Header>
<Credit>-20</Credit>
</Header>
<Detail>
<Debit>10</Debit>
</Detail>
<Detail>
<Debit>9</Debit>
</Detail>
<Detail>
<Debit>1</Debit>
</Detail>
</Invoice>
<Invoice>
<Header>
<Credit>-10</Credit>
</Header>
<Detail>
<Debit>7</Debit>
</Detail>
<Detail>
<Debit>3</Debit>
</Detail>
</Invoice>
</Invoices>

outbound:
<ns0:Invoices xmlns:ns0="http://www.google.com">
<ns0:TotalFileCredit>-30</ns0:TotalFileCredit>
<ns0:TotalFileDebit>30</ns0:TotalFileDebit>
<ns0:Invoice>
<ns0:TotalInvoiceCredit>-20</ns0:TotalInvoiceCredit>
<ns0:TotalInvoiceDebit>20</ns0:TotalInvoiceDebit>
<ns0:Header>
<ns0:Credit>-20</ns0:Credit>
</ns0:Header>
<ns0:Detail>
<ns0:Debit>10</ns0:Debit>
</ns0:Detail>
<ns0:Detail>
<ns0:Debit>9</ns0:Debit>
</ns0:Detail>
<ns0:Detail>
<ns0:Debit>1</ns0:Debit>
</ns0:Detail>
</ns0:Invoice>
<ns0:Invoice>
<ns0:TotalInvoiceCredit>-10</ns0:TotalInvoiceCredit>
<ns0:TotalInvoiceDebit>10</ns0:TotalInvoiceDebit>
<ns0:Header>
<ns0:Credit>-10</ns0:Credit>
</ns0:Header>
<ns0:Detail>
<ns0:Debit>7</ns0:Debit>
</ns0:Detail>
<ns0:Detail>
<ns0:Debit>3</ns0:Debit>
</ns0:Detail>
</ns0:Invoice>
</ns0:Invoices>



Obviously the inbound and outbound xml document instances could share a same schema. Here's the schema code:


<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.google.com"
targetNamespace="http://www.google.com"
elementFormDefault="qualified"
attributeFormDefault="unqualified"
>
<xs:complexType name="Detail">
<xs:sequence>
<xs:element name="Debit" type="xs:int" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="Header">
<xs:sequence>
<xs:element name="Credit" type="xs:int" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="Invoice">
<xs:sequence>
<xs:element minOccurs="0" name="TotalInvoiceCredit" type="xs:int" />
<xs:element minOccurs="0" name="TotalInvoiceDebit" type="xs:int" />
<xs:element name="Header" type="Header" />
<xs:element maxOccurs="unbounded" name="Detail" type="Detail" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="Invoices">
<xs:sequence>
<xs:element minOccurs="0" name="TotalFileCredit" type="xs:int" />
<xs:element minOccurs="0" name="TotalFileDebit" type="xs:int" />
<xs:element maxOccurs="unbounded" name="Invoice" type="Invoice" />
</xs:sequence>
</xs:complexType>
<xs:element name="Invoices" type="Invoices" />
</xs:schema>


Here's the map I have used:



In the scripting functoid, I used the XSLT Call Template below:


<xsl:template name="MyXsltConcatTemplate">
<xsl:param name="param1" />
<xsl:element name="ns0:TotalInvoiceDebit"
namespace="http://www.google.com">
<xsl:value-of
select="sum(*[local-name()='Detail']/*[local-name()='Debit'])" />
</xsl:element>
</xsl:template>

We couldn't use the inline xslt here since we need to pass in a local node "Invoice" that occurs multiple times in the inbound document. You can't pass in any parameter using the inline xslt script. The inline xslt call template, however, allows you to pass in a local node and you can apply your xslt transformation within the scope of passed parameter. In this case it is "param1" and it refers to one of the "Invoice" element of the xml document.


Followers