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>