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>&lt;No Values&gt;</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.

Recommended Answers

All 5 Replies

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 <Location> and <Owner> (we can forget about <plCompany_Country> 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>

This was of great help for me to see how to walk thru the structure. Thanks so much.

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>
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.