I ran into a complicated XSLT question.
Input.xml
<ITEM> <ID>00050802</PRODUCTID> <ISBN>SCKTVO</PRODUCTEAN> <NAME>VOYAGE</PRODUCTNAME> <OTHERDATA></OTHERDATA> </ITEM> <ITEM> <ID>00033802</PRODUCTID> <ISBN>OPDFJD</PRODUCTEAN> <NAME>TEST</PRODUCTNAME> <OTHERDATA></OTHERDATA> </ITEM>
Here I want to add a new element <DESCRIPTION>. The tricky part: the content are in separate files, the file name of the description file is the : (00050802.html,00033802.html === <ID>.html). The .html contains some html code, so the content should be enclosed in CDATA.
Output.xml
<ITEM>
<ID>00050802</PRODUCTID>
<ISBN>SCKTVO</PRODUCTEAN>
<NAME>VOYAGE</PRODUCTNAME>
<OTHERDATA></OTHERDATA>
<DESCRIPTION><![CDATA[
00050802.html content
]]></DESCRIPTION>
</ITEM>
<ITEM>
<ID>00033802</PRODUCTID>
<ISBN>OPDFJD</PRODUCTEAN>
<NAME>TEST</PRODUCTNAME>
<OTHERDATA></OTHERDATA>
<DESCRIPTION><![CDATA[
00033802.html content
]]></DESCRIPTION>
</ITEM>
XSLT version does not matter.
Advertisement
Answer
You can retrieve the content of the HTML file using unparsed-text() and ensure that the content of the DESCRIPTION element is serialized with CDATA by using the cdata-section-elements attribute on the xsl:output declaration:
<?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"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output cdata-section-elements="DESCRIPTION"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ITEM">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<DESCRIPTION>
<xsl:variable name="filename" select="concat(ID, '.html')"/>
<xsl:value-of select="$filename"/>
<xsl:value-of select="unparsed-text($filename)"/>
</DESCRIPTION>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>