Skip to content
Advertisement

XSLT: add element, read content from file

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>
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement