I have some XML outputted from an SQL-Server, that I then need to turn into multiple HTML files. This I have done with moderate success using Saxon and
<xsl:result-document>, but Saxon is throwing an error and I don't know how to resolve it. Maybe someone can offer some advice? This is a long question, for which I apologise... OS= Windows XP Pro, Saxon=8.8
XML example:
Expand|Select|Wrap|Line Numbers
- <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
- <A>
- <A_ID>10</A_ID>
- <A_NAME>Test_A</A_NAME>
- <B>
- <B_ID>20</B_ID>
- <B_NAME>Test_B</B_NAME>
- <C>
- <C_ID>30</C_ID>
- <C_NAME>Test_C1</C_NAME>
- </C>
- <C>
- <C_ID>31</C_ID>
- <C_NAME>Test_C2</C_NAME>
- </C>
- </B>
- </A>
- <A>
- <A_ID>11</A_ID>
- <A_NAME>Test_AA</A_NAME>
- <B>
- <B_ID>21</B_ID>
- <B_NAME>Test_BB</B_NAME>
- <C>
- <C_ID>32</C_ID>
- <C_NAME>Test_C3</C_NAME>
- </C>
- <C>
- <C_ID>33</C_ID>
- <C_NAME>Test_C4</C_NAME>
- </C>
- </B>
- </A>
- </ROOT>
1) Output to an HTML file called index.html that will be stored in the folder "Output\Test_A". The folder "Test_A" is determined and created dynamically from the tag <A_NAME>. The index.html file contains the values of <A_ID> and <A_NAME>. This I have done successfully.
2) Output to an HTML file called index.html that will be stored in the folder "Output\Test_A\Test_B". The folder "Test_B" is determined and created dynamically from the tag <B_NAME> ONLY IF the value of tag <A_NAME> = "Test_A". The index.html file contains the values of <B_ID> and <B_NAME>. This I have done successfully. For other nodes, the IF and the name of the folder is changed according to the value of <A_NAME>.
3) Tricky part. Finally output to an HTML file called the value of <C_ID>, i.e. 30.html that will be stored in the location "Output\Test_A\Test_B" ONLY IF the value of tag <B_NAME> = "Test_B". This file contains the values of <C_ID> and <C_NAME>. For other nodes, the IF and the name of the folder is changed according to the value of <B_NAME>.
4) This continues as above for all other nodes in the XML file.
On running the XSL file (see below) against the XML with Saxon, the first part of the process is successfully achieved and I end up with this file structure, and the HTML files contain what they should:
Expand|Select|Wrap|Line Numbers
- output--
- |
- Test_A--
- |
- index.htm
- Test_B--
- |
- index.htm
- Test_AA--
- |
- index.htm
- Test_BB--
- |
- index.htm
Error on line 82 of file: c:\test\style.xsl
XPTY0004: A sequence of more than one item is not allowed as the second argument of concat()
Transformation failed: Run-time errors were reported.
Anyone any ideas? I am stumped... Thanks.
XSL file:
Expand|Select|Wrap|Line Numbers
- <?xml version="1.0" encoding="UTF-8"?>
- <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
- <xsl:output method="text"/>
- <xsl:output method="html" indent="yes" name="html"/>
- <xsl:template match="/">
- <xsl:for-each select="//A">
- <xsl:variable name="filename" select="concat('output/',A_NAME,'/index.htm')" />
- <xsl:value-of select="$filename" />
- <xsl:result-document href="{$filename}" format="html">
- <html>
- <head>
- <meta http-equiv="Content-Language" content="en" />
- <meta http-equiv="Content-Type" content="text/html; charset=windows-1252" />
- <title><xsl:value-of select="A_NAME"/></title>
- <link rel="StyleSheet" href="../style.css" type="text/css"></link>
- </head>
- <body>
- <h4>Criterion</h4>
- <hr />
- <h5>Criterion Name:</h5>
- <p><xsl:value-of select="A_NAME"/></p>
- <h5>Criterion ID:</h5>
- <p><xsl:value-of select="A_ID"/></p>
- <hr />
- </body>
- </html>
- </xsl:result-document>
- <xsl:if test="A_NAME='Test_A'">
- <xsl:variable name="filename" select="concat('output/Test_A/',B/B_NAME,'/index.htm')" />
- <xsl:value-of select="$filename" />
- <xsl:result-document href="{$filename}" format="html">
- <html>
- <head>
- <meta http-equiv="Content-Language" content="en" />
- <meta http-equiv="Content-Type" content="text/html; charset=windows-1252" />
- <title><xsl:value-of select="B/B_NAME"/></title>
- <link rel="StyleSheet" href="../../style.css" type="text/css"></link>
- </head>
- <body>
- <h4>Sub-Criterion</h4>
- <hr />
- <h5>Sub-Criterion Name:</h5>
- <p><xsl:value-of select="B/B_NAME"/></p>
- <h5>Sub-Criterion ID:</h5>
- <p><xsl:value-of select="B/B_ID"/></p>
- <hr />
- </body>
- </html>
- </xsl:result-document>
- </xsl:if>
- <xsl:if test="A_NAME='Test_AA'">
- <xsl:variable name="filename" select="concat('output/Test_AA/',B/B_NAME,'/index.htm')" />
- <xsl:value-of select="$filename" />
- <xsl:result-document href="{$filename}" format="html">
- <html>
- <head>
- <meta http-equiv="Content-Language" content="en" />
- <meta http-equiv="Content-Type" content="text/html; charset=windows-1252" />
- <title><xsl:value-of select="B/B_NAME"/></title>
- <link rel="StyleSheet" href="../../style.css" type="text/css"></link>
- </head>
- <body>
- <h4>Sub-Criterion</h4>
- <hr />
- <h5>Sub-Criterion Name:</h5>
- <p><xsl:value-of select="B/B_NAME"/></p>
- <h5>Sub-Criterion ID:</h5>
- <p><xsl:value-of select="B/B_ID"/></p>
- <hr />
- </body>
- </html>
- </xsl:result-document>
- </xsl:if>
- </xsl:for-each>
- <xsl:for-each select="//B">
- <xsl:if test="B_NAME='Test_B'">
- <xsl:variable name="filename" select="concat('output/Test_A/Test_B/',C/C_ID,'.htm')" />
- <xsl:value-of select="$filename" />
- <xsl:result-document href="{$filename}" format="html">
- <html>
- <head>
- <meta http-equiv="Content-Language" content="en" />
- <meta http-equiv="Content-Type" content="text/html; charset=windows-1252" />
- <title><xsl:value-of select="C/C_NAME"/></title>
- <link rel="StyleSheet" href="../style.css" type="text/css"></link>
- </head>
- <body>
- <h4>Metric</h4>
- <hr />
- <h5>Metric Name:</h5>
- <p><xsl:value-of select="C/C_NAME"/></p>
- <h5>Metric ID:</h5>
- <p><xsl:value-of select="C/C_ID"/></p>
- <hr />
- </body>
- </html>
- </xsl:result-document>
- </xsl:if>
- <xsl:if test="B_NAME='Test_BB'">
- <xsl:variable name="filename" select="concat('output/Test_AA/Test_BB/',C/C_ID,'.htm')" />
- <xsl:value-of select="$filename" />
- <xsl:result-document href="{$filename}" format="html">
- <html>
- <head>
- <meta http-equiv="Content-Language" content="en" />
- <meta http-equiv="Content-Type" content="text/html; charset=windows-1252" />
- <title><xsl:value-of select="//METRIC_NAME"/></title>
- <link rel="StyleSheet" href="../style.css" type="text/css"></link>
- </head>
- <body>
- <h4>Metric</h4>
- <hr />
- <h5>Metric Name:</h5>
- <p><xsl:value-of select="C/C_NAME"/></p>
- <h5>Metric ID:</h5>
- <p><xsl:value-of select="C/C_ID"/></p>
- <hr />
- </body>
- </html>
- </xsl:result-document>
- </xsl:if>
- </xsl:for-each>
- </xsl:template>
- </xsl:stylesheet>