Working on a xslt 1.0 stylesheet for mapping of an address service. I have lookup up some of the examples for the Muenchian method for grouping in xslt 1.0, but i still am confused on the xsl:key and nested xsl:for-each loops.
I am only concerned with the InputAddress
node-set. There may be multiple (but not always) InputAddress
nodesets as part of the parent ValidateRequest
node so i need to loop thru all iterations of InputAddress
and then perform the mapping to the pertinent elements.
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:v1="blah" xmlns:v3="blah2">
<soap:Header/>
<soap:Body>
<v1:validate>
<ValidateRequest>
<!--One or more repetitions:-->
<InputAddress>
<v3:City>Redmond</v3:City>
<v3:Territory>
<v3:Name>Washington</v3:Name>
<FIPSStateAlphaCode>WA</FIPSStateAlphaCode>
</v3:Territory>
<v3:PostalCode>98007</v3:PostalCode>
<v3:Country>
<!--Zero or more repetitions:-->
<v3:Name>US</v3:Name>
</v3:Country>
<v3:FullAddress>123 main street</v3:FullAddress>
<v3:FullAddress>Ste 200</v3:FullAddress>
</InputAddress>
<InputAddress>
<v3:City>Seattle</v3:City>
<v3:Territory>
<v3:Name>Washington</v3:Name>
<FIPSStateAlphaCode>WA</FIPSStateAlphaCode>
</v3:Territory>
<v3:PostalCode>98103</v3:PostalCode>
<v3:Country>
<!--Zero or more repetitions:-->
<v3:Name>US</v3:Name>
</v3:Country>
<v3:FullAddress>987 1st street</v3:FullAddress>
</InputAddress>
</ValidateRequest>
</v1:validate>
</soap:Body>
<soap:Body>
<wsdl:WS_MDM_Address_ValidationRequest>
<wsdl:WS_MDM_Address_ValidationRequestElement>
<wsdl:Address_Line1>123 main street</wsdl:Address_Line1>
<wsdl:Address_Line2>Ste 200</wsdl:Address_Line2>
<wsdl:City>Redmond</wsdl:City>
<wsdl:State>WA</wsdl:State>
<wsdl:Postal_Code>98007</wsdl:Postal_Code>
<wsdl:Country>US</wsdl:Country>
</wsdl:WS_MDM_Address_ValidationRequestElement>
<wsdl:WS_MDM_Address_ValidationRequestElement>
<wsdl:Address_Line1>987 1st Street</wsdl:Address_Line1>
<wsdl:City>Seattle</wsdl:City>
<wsdl:State>WA</wsdl:State>
<wsdl:Postal_Code>98103</wsdl:Postal_Code>
<wsdl:Country>US</wsdl:Country>
</wsdl:WS_MDM_Address_ValidationRequestElement>
</wsdl:WS_MDM_Address_ValidationRequest>
</soap:Body>
<xsl:key name="AddressDoctor" match="v3:FullAddress" use="//v3:FullAddress" />
<xsl:variable name="address" select="/*[local-name()='Envelope']/*[local-name()='Body']/*[local-name()='validate']/ValidateRequest/InputAddress"/>
<xsl:template name="addressdoctor">
<soap:Envelope>
<soap:Header>
<xsl:copy-of select="/*[local-name()='Envelope']/*[local-name()='Header']/*"/>
</soap:Header>
<soap:Body>
<wsdl:WS_MDM_Address_ValidationRequest>
<xsl:for-each select="key('AddressDoctor', '.')">
<wsdl:WS_MDM_Address_ValidationRequestElement>
<xsl:for-each select="[not($FullAddress = preceding::text()=$FullAddress)]">
<xsl:element name="wsdl:{concat('Address_Line',position())}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
<wsdl:City>
<xsl:for-each select="$address/*[local-name()='City']">
<xsl:value-of select="$address/*[local-name()='City']"/>
</xsl:for-each>
</wsdl:City>
<wsdl:State>
<xsl:value-of select="$address/*[local-name()='Territory']/*[local-name()='FIPSStateAlphaCode']"/>
</wsdl:State>
<wsdl:Postal_Code>
<xsl:value-of select="$address/*[local-name()='PostalCode']"/>
</wsdl:Postal_Code>
<wsdl:Country>
<xsl:value-of select="$address/*[local-name()='Country']/*[local-name()='Name']"/>
</wsdl:Country>
</wsdl:WS_MDM_Address_ValidationRequestElement>
</xsl:for-each>
</wsdl:WS_MDM_Address_ValidationRequest>
</soap:Body>
</soap:Envelope>
</xsl:template>
Based on the input XML you have provided I don't see that there is a need for any type of grouping. Which is a good thing considering you are working with XSLT 1.0 since grouping can be a bit difficult to get right. You can instead start with a simple identity template and then override a few of the elements to display the output you are looking for.
Here is the XSL:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:v1="blah" xmlns:v3="blah2" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<xsl:output method="xml" indent="yes" />
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ValidateRequest">
<wsdl:WS_MDM_Address_ValidationRequest>
<xsl:apply-templates/>
</wsdl:WS_MDM_Address_ValidationRequest>
</xsl:template>
<xsl:template match="InputAddress">
<wsdl:WS_MDM_Address_ValidationRequestElement>
<wsdl:Address_Line1>
<xsl:value-of select="v3:FullAddress[1]"/>
</wsdl:Address_Line1>
<xsl:if test="v3:FullAddress[2]">
<wsdl:Address_Line2>
<xsl:value-of select="v3:FullAddress[2]"/>
</wsdl:Address_Line2>
</xsl:if>
<wsdl:City>
<xsl:value-of select="v3:City"/>
</wsdl:City>
<wsdl:State>
<xsl:value-of select="v3:Territory/FIPSStateAlphaCode"/>
</wsdl:State>
<wsdl:Postal_Code>
<xsl:value-of select="v3:PostalCode"/>
</wsdl:Postal_Code>
<wsdl:Country>
<xsl:value-of select="v3:Country/v3:Name"/>
</wsdl:Country>
</wsdl:WS_MDM_Address_ValidationRequestElement>
</xsl:template>
<xsl:template match="v1:validate">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
This will produce the output that you are looking for based on the example you provided.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.