I need help with some XSLT...
I have the following XML input document:
<?xml version="1.0" encoding="UTF-8"?>
<report xmlns="http://jasperreports.sourceforge.net/jasperreports"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd"
repName="FirstElementTemp"
date="10-05-2001">
<element1>
<![CDATA[]]>
</element1>
<element2 name="secondElement"/>
<head>
<hText x="10" y="20">
<textVal>TEXT 1</textVal>
</hText>
<hText x="10" y="30">
<textVal>TEXT 2</textVal>
</hText>
<hText x="10" y="40">
<textVal>TEXT 3</textVal>
</hText>
</head>
<body/>
</report>
And I'm trying to transform it using the following XSLT stylesheet:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xpath-default-namespace="http://jasperreports.sourceforge.net/jasperreports"
xmlns:jsp="http://jasperreports.sourceforge.net/jasperreports"
xmlns="http://jasperreports.sourceforge.net/jasperreports"
exclude-result-prefixes="xs jsp"
expand-text="yes"
version="3.0">
<xsl:param name="doc2" xmlns="">
<secondDoc>
<elementTemps>
<elemTemp ID="1" name="FirstElementTemp" />
<elemTemp ID="2" name="SecondTemplate" />
</elementTemps>
<elementReps>
<elemRep tmpID="1" name="FirstElementRep" >
<value forCDATA="THIS IS THE VALUE FOR CDATA 1">FIRST DATA 1</value>
<value forCDATA="THIS IS THE VALUE FOR CDATA 1">FIRST DATA 2</value>
<value forCDATA="THIS IS THE VALUE FOR CDATA 1">FIRST DATA 3</value>
</elemRep>
<elemRep tmpID="2" name="SecondTemplate">
<value forCDATA="THIS IS THE VALUE FOR CDATA 2">SECOND DATA</value>
</elemRep>
</elementReps>
</secondDoc>
</xsl:param>
<xsl:output indent="yes" cdata-section-elements="element1"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:key name="key1" match="elemTemp" use="@name" xpath-default-namespace=""/>
<xsl:key name="key2" match="elemRep" use="@tmpID" xpath-default-namespace=""/>
<xsl:template match="report/*[1]">
<xsl:variable name="temp" select="key('key1', ../@repName, $doc2)"/>
<xsl:variable name="rep" select="key('key2', $temp/@ID, $doc2)"/>
<valueIs>
<xsl:value-of select="$rep/value[1]" xpath-default-namespace=""/>
</valueIs>
<element1>
<xsl:value-of select="$rep/value[1]/@forCDATA" xpath-default-namespace=""/>
</element1>
</xsl:template>
<xsl:template match="element2">
<xsl:copy>
<xsl:copy-of select="@*"/>
<newChild>THIS IS THE NEW CHILD</newChild>
</xsl:copy>
</xsl:template>
<xsl:template match="report/body">
<xsl:variable name="temp2" select="key('key1', ancestor::report/@repName, $doc2)"/>
<xsl:variable name="rep2" select="key('key2', $temp2/@ID, $doc2)"/>
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:for-each select="$rep2/value" xpath-default-namespace="">
<xsl:variable name="vCount" select="count(preceding-sibling::value)+1"/>
<bText>
<xsl:attribute name="x">
<xsl:value-of select="/report/head/hText[$vCount]/@x"/>
</xsl:attribute>
<xsl:attribute name="y">
<xsl:value-of select="/report/head/hText[$vCount]/@y"/>
</xsl:attribute>
<textVal>
<xsl:value-of select="current()"/>
</textVal>
</bText>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
As you can see, I'm using a second XML input document (doc2) that I pass to the XSLT as a <xsl:param>
. The section of the XSLT stylesheet that isn't working is the last <xsl:tempplate>
, <xsl:template match="report/body">
Basically, this is the output I want to get:
<?xml version="1.0" encoding="UTF-8"?>
<report xmlns="http://jasperreports.sourceforge.net/jasperreports"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd"
repName="FirstElementTemp"
date="10-05-2001">
<valueIs>FIRST DATA 1</valueIs>
<element1><![CDATA[THIS IS THE VALUE FOR CDATA 1]]></element1>
<element2 name="secondElement">
<newChild>THIS IS THE NEW CHILD</newChild>
</element2>
<head>
<hText x="10" y="20">
<textVal>TEXT 1</textVal>
</hText>
<hText x="10" y="30">
<textVal>TEXT 2</textVal>
</hText>
<hText x="10" y="40">
<textVal>TEXT 3</textVal>
</hText>
</head>
<body>
<bText x="10" y="20">
<textVal>FIRST DATA 1</textVal>
</bText>
<bText x="10" y="30">
<textVal>FIRST DATA 2</textVal>
</bText>
<bText x="10" y="40">
<textVal>FIRST DATA 3</textVal>
</bText>
</body>
</report>
But this is the output I'm really getting:
<?xml version="1.0" encoding="UTF-8"?>
<report xmlns="http://jasperreports.sourceforge.net/jasperreports"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd"
repName="FirstElementTemp"
date="10-05-2001">
<valueIs>FIRST DATA 1</valueIs>
<element1><![CDATA[THIS IS THE VALUE FOR CDATA 1]]></element1>
<element2 name="secondElement">
<newChild>THIS IS THE NEW CHILD</newChild>
</element2>
<head>
<hText x="10" y="20">
<textVal>TEXT 1</textVal>
</hText>
<hText x="10" y="30">
<textVal>TEXT 2</textVal>
</hText>
<hText x="10" y="40">
<textVal>TEXT 3</textVal>
</hText>
</head>
<body>
<bText x="" y="">
<textVal>FIRST DATA 1</textVal>
</bText>
<bText x="" y="">
<textVal>FIRST DATA 2</textVal>
</bText>
<bText x="" y="">
<textVal>FIRST DATA 3</textVal>
</bText>
</body>
</report>
As you can see I'm not being able to get the value from <xsl:value-of select="/report/head/hText[$vCount]/@x"/>
and <xsl:value-of select="/report/head/hText[$vCount]/@y"/>
, to put inside the x
and y
attributes of the <bText>
elements, respectively.
I think this is because in the <xsl:for-each>
I go inside the second XML input document (doc2
), and then in the <xsl:value-of>
elements I try to go back to the first XML input document. Also, I'm using the current()
function and so I can confirm that I'm in the context of the second input XML document (doc2
).
So what I need to do is change the namespace back to "http://jasperreports.sourceforge.net/jasperreports"
or change the context to the context of the first input XML document.
How can I do this? I tried doing <xsl:value-of select="/jsp:report/jsp:head/jsp:hText[$vCount]/@x"/>
because I defined that namespace in the <xsl:stylesheet>
element but it didn't work.
XSLT FIDDLE AT: https://xsltfiddle.liberty-development.net/94hvTzn
Thank you!
Alexandre Jacinto