This is the usual "I'm new to XSLT and need help" plea ... I am trying to parse an XML document and create a "like" structure as output while performing some mapping functions. In trying to produce the output structure, I cannot seem to figure out how to get at the element values to process. Here is a sample of the input document:
<AccountWS_AccountQueryPage_Output xmlns="urn:crmondemand/ws/account/10/2004">
<LastPage>true</LastPage>
<ListOfAccount xmlns="urn:/crmondemand/xml/account">
- <Account>
<AccountId>ADOA-4FKPN1</AccountId>
<CreatedDate>10/17/2010 20:00:24</CreatedDate>
<Description/>
<Location>PARIS LA DEFENSE</Location>
<MainPhone/>
<ModifiedDate>10/18/2010 00:02:18</ModifiedDate>
<AccountName>AUTOMOBILES CITROEN [200000000044891]</AccountName>
<Owner>3DS</Owner>
<AccountType>Customer</AccountType>
<plz_DS1_Group_Size/>
<plz_DS1_Site_SubIndustry/>
<plz_DS1_Site_Industry/>
<plCompany_Country><No Values></plCompany_Country>
<plz_DS1_Site_Type/>
<stDUNS_Number/>
<stDS_Company_ID>200000000044891</stDS_Company_ID>
<stz_DS1_SIC_Code/>
<stLeading_Channel/>
<ParentAccountExternalSystemId/>
<PrimaryShipToCity>PARIS LA DEFENSE</PrimaryShipToCity>
<PrimaryShipToCountry>Canada</PrimaryShipToCountry>
<PrimaryShipToPostalCode>92094</PrimaryShipToPostalCode>
<PrimaryShipToProvince/>
<PrimaryShipToState/>
<PrimaryShipToStreetAddress>TOUR MANHATTAN</PrimaryShipToStreetAddress>
</Account>
<Account>
<AccountId>ADOA-4FKPN1</AccountId>
<CreatedDate>10/17/2010 20:00:24</CreatedDate>
<Description/>
<Location>PARIS LA DEFENSE</Location>
<MainPhone/>
<ModifiedDate>10/18/2010 00:02:18</ModifiedDate>
<AccountName>AUTOMOBILES CITROEN [200000000044891]</AccountName>
<Owner>3DS</Owner>
<AccountType>Customer</AccountType>
<plz_DS1_Group_Size/>
<plz_DS1_Site_SubIndustry/>
<plz_DS1_Site_Industry/>
<plCompany_Country>Canada</plCompany_Country>
<plz_DS1_Site_Type/>
<stDUNS_Number/>
<stDS_Company_ID>200000000044891</stDS_Company_ID>
<stz_DS1_SIC_Code/>
<stLeading_Channel/>
<ParentAccountExternalSystemId/>
<PrimaryShipToCity>PARIS LA DEFENSE</PrimaryShipToCity>
<PrimaryShipToCountry>Canada</PrimaryShipToCountry>
<PrimaryShipToPostalCode>92094</PrimaryShipToPostalCode>
<PrimaryShipToProvince/>
<PrimaryShipToState/>
<PrimaryShipToStreetAddress>TOUR MANHATTAN</PrimaryShipToStreetAddress>
</Account>
</ListOfAccount>
</AccountWS_AccountQueryPage_Output>
And the XSLT I have so far as a sample (just manipulating a few attributes for now):
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="PickLists" select="document('Picklist_data.xml')"/>
<xsl:template match="*">
<AccountWS_AccountQueryPage_Output xmlns="urn:crmondemand/ws/account/10/2004">
<LastPage><xsl:value-of select="*:LastPage"/></LastPage>
<ListOfAccount xmlns="urn:/crmondemand/xml/account">
<xsl:variable select="*:plCompany_Country" name="plCompany_Country"/>
<xsl:apply-templates select="//Account"/>
<xsl:for-each select="*">
<Account>
<Location><xsl:value-of select="*:Location"/></Location>
<Owner><xsl:value-of select="*:Owner"/></Owner>
<plCompany_Country>
<xsl:value-of
select="$PickLists/*:ListOfParentPicklistValue/*:ParentPicklistValue[*:ParentFieldName='plCompany_Country']/*:ListOfPicklistValue/*:PicklistValue[*:Code= $plCompany_Country]/*:DisplayValue"
/>
</plCompany_Country>
</Account>
</xsl:for-each>
</ListOfAccount>
</AccountWS_AccountQueryPage_Output>
</xsl:template>
</xsl:stylesheet>
and the output I am getting:
<?xml version="1.0" encoding="UTF-8"?>
<AccountWS_AccountQueryPage_Output xmlns="urn:crmondemand/ws/account/10/2004">
<LastPage>true</LastPage>
<ListOfAccount xmlns="urn:/crmondemand/xml/account">
<Account>
<Location/>
<Owner/>
<plCompany_Country/>
</Account>
<Account>
<Location/>
<Owner/>
<plCompany_Country/>
</Account>
</ListOfAccount>
</AccountWS_AccountQueryPage_Output>
so in the for-each loop, I am not able to figure out exactly how to reference the values from the source document. I would greatly appreciate any advice/tips on what to do.
You've got a couple conflicting ideals in this transformation. For example, you're doing an apply-templates on "//Account", but there is no "Account" node in the source document (because it's in the default namespace.)
There's some logic flaws in this, but I don't understand what the DESIRED output is supposed to look like so I can't help. Can you provide an sample DESIRED output document of what it should look like after it goes through your transformation. If I can see how things are supposed to be mapped, I'll fix it.
First, thanks for having a look and responding. Second, sorry for the poor description. I think for what I need to do, I just want to be able to get at the values of and (we can forget about for now as I just provided it in the XSLT to show how I need to use the value for mapping with another external source document). I think if I can see how to parse all the attributes under Account while handling all the occurrences of Account I can produce my output. So, for this example, it would be a straight copy of the values. Hope this is more clear.
Try this to start.
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="PickLists" select="document('Picklist_data.xml')"/>
<xsl:template match="/">
<xsl:apply-templates select="*:AccountWS_AccountQueryPage_Output"/>
</xsl:template>
<xsl:template match="*:AccountWS_AccountQueryPage_Output">
<xsl:copy>
<xsl:apply-templates select="*:LastPage"/>
<xsl:apply-templates select="*:ListOfAccount"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*:ListOfAccount">
<xsl:copy>
<xsl:apply-templates select="*:Account"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*:Account">
<xsl:variable select="*:plCompany_Country" name="plCompany_Country"/>
<xsl:copy>
<xsl:apply-templates select="*:Location"/>
<xsl:apply-templates select="*:Owner"/>
<xsl:element name="plCompany_Country" >
<xsl:value-of select="$PickLists/*:ListOfParentPicklistValue/*:ParentPicklistValue[*:ParentFieldName='plCompany_Country']/*:ListOfPicklistValue/*:PicklistValue[*:Code= $plCompany_Country]/*:DisplayValue"/>
</xsl:element>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:value-of select="."/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>Just for completeness, here is an XSL1.0 solution. A wildcard ('*') namespace prefix is not permitted in XSLT1.0. The solution is to match using the local-name() function.
xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="*[local-name()='AccountWS_AccountQueryPage_Output']"/>
</xsl:template>
<xsl:template match="*[local-name()='AccountWS_AccountQueryPage_Output']">
<xsl:copy>
<xsl:apply-templates select="*[local-name()='LastPage']"/>
<xsl:apply-templates select="*[local-name()='ListOfAccount']"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[local-name()='ListOfAccount']">
<xsl:copy>
<xsl:apply-templates select="*[local-name()='Account']"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[local-name()='Account']">
<xsl:copy>
<xsl:apply-templates select="*[local-name()='Location']"/>
<xsl:apply-templates select="*[local-name()='Owner']"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:value-of select="."/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>