Reputation: 23
I'm brand new to XSLT so I'm sure this is really simple, but I can't get it. I am trying to transform a report outputed into simple xml into a pipe delimited file. I can't figure out how to access wd:SSN from inside a template that is called from within a for-each. The xml output from a report looks something like this.
<wd:Report_Data xmlns:wd="urn:com.workday.report/Report_ABC">
<wd:Report_Entry>
<wd:Company>
<wd:Company_Code>123</wd:Company_Code>
</wd:Company>
<wd:Employee_Last_Name>Smith</wd:Employee_Last_Name>
<wd:Employee_First_Name>Joe</wd:Employee_First_Name>
<wd:SSN>123456789</wd:SSN>
<wd:Street_Address>123 First St</wd:Street_Address>
<wd:City>Colorado Springs</wd:City>
<wd:State_Province>CO</wd:State_Province>
<wd:ZIP_Code>80927</wd:ZIP_Code>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:Company>
<wd:Company_Code>123</wd:Company_Code>
</wd:Company>
<wd:Employee_Last_Name>Smith</wd:Employee_Last_Name>
<wd:Employee_First_Name>Sally</wd:Employee_First_Name>
<wd:SSN>123456790</wd:SSN>
<wd:Street_Address>123 First St</wd:Street_Address>
<wd:City>Colorado Springs</wd:City>
<wd:State_Province>CO</wd:State_Province>
<wd:ZIP_Code>80927</wd:ZIP_Code>
</wd:Report_Entry>
Then my code looks like this
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output method="text" indent="no"/>
<xsl:template match="wd:Report_Data" xmlns:wd="urn:com.workday.report/Report_ABC">
<!-- Loop thru employee records for Company 123 -->
<xsl:for-each select="wd:Report_Entry[wd:Company/wd:Company_Code = '123']">
<xsl:call-template name="ProcessCompanyEmployee"/>
</xsl:for-each>
</xsl:template>
<!-- Process Company Employee -->
<xsl:template name="ProcessCompanyEmployee">
<!-- EMP Employee Record -->
<xsl:text>EMP|N|N</xsl:text>
<xsl:text>|</xsl:text>
<xsl:text>|</xsl:text>
<xsl:value-of select="wd:SSN"/>
<xsl:text>||</xsl:text>
<xsl:call-template name="insertNewLine"/>
</xsl:template>
Thanks for your help!
Upvotes: 2
Views: 328
Reputation: 52878
You're binding the namespace on one xsl:template, but also trying to use it in another xsl:template.
Try moving your xmlns:wd declaration up to the xsl:stylesheet.
Example...
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:wd="urn:com.workday.report/Report_ABC">
<xsl:strip-space elements="*"/>
<xsl:output method="text" indent="no"/>
<xsl:template match="wd:Report_Data">
<!-- Loop thru employee records for Company 123 -->
<xsl:for-each select="wd:Report_Entry[wd:Company/wd:Company_Code = '123']">
<xsl:call-template name="ProcessCompanyEmployee"/>
</xsl:for-each>
</xsl:template>
<!-- Process Company Employee -->
<xsl:template name="ProcessCompanyEmployee">
<!-- EMP Employee Record -->
<xsl:text>EMP|N|N</xsl:text>
<xsl:text>|</xsl:text>
<xsl:text>|</xsl:text>
<xsl:value-of select="wd:SSN"/>
<xsl:text>||</xsl:text>
<xsl:call-template name="insertNewLine"/>
</xsl:template>
<xsl:template name="insertNewLine">
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
Also, since you're using XSLT 2.0, you could not use a prefix at all in your XPath's and add:
xpath-default-namespace="urn:com.workday.report/Report_ABC"
to xsl:stylesheet.
Example...
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xpath-default-namespace="urn:com.workday.report/Report_ABC">
<xsl:strip-space elements="*"/>
<xsl:output method="text" indent="no"/>
<xsl:template match="Report_Data">
<!-- Loop thru employee records for Company 123 -->
<xsl:for-each select="Report_Entry[Company/Company_Code = '123']">
<xsl:call-template name="ProcessCompanyEmployee"/>
</xsl:for-each>
</xsl:template>
<!-- Process Company Employee -->
<xsl:template name="ProcessCompanyEmployee">
<!-- EMP Employee Record -->
<xsl:text>EMP|N|N</xsl:text>
<xsl:text>|</xsl:text>
<xsl:text>|</xsl:text>
<xsl:value-of select="SSN"/>
<xsl:text>||</xsl:text>
<xsl:call-template name="insertNewLine"/>
</xsl:template>
<xsl:template name="insertNewLine">
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1
Reputation: 568
In your for-each select
you've got [wd:Company/wd:Company_Code = '123']
, but the XML doesn't contain a wd:Company
element.
The following template works to transform your XML:
<xsl:template match="/">
<xsl:for-each select="//wd:Report_Entry[wd:Company_Code = '123']">
<xsl:text>EMP|N|N</xsl:text>
...
<xsl:value-of select="wd:SSN"/>
...
</xsl:for-each>
</xsl:template>
Using your original matches/selects as follows also works:
<xsl:template match="wd:Report_Data">
<xsl:for-each select="wd:Report_Entry[wd:Company_Code = '123']">
When testing XSLT it helps to reduce use of templates and get it operating to select one element (say SSN), then build back up from there.
Upvotes: 0