471,073 Members | 1,116 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,073 software developers and data experts.

Saxon & <xsl:result-document> and error

I have been having some trouble getting my XSL style sheet to parse correctly.

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
  1. <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  2. <A>
  3.     <A_ID>10</A_ID>
  4.     <A_NAME>Test_A</A_NAME>
  5.     <B>
  6.         <B_ID>20</B_ID>
  7.         <B_NAME>Test_B</B_NAME>
  8.         <C>
  9.             <C_ID>30</C_ID>
  10.             <C_NAME>Test_C1</C_NAME>
  11.         </C>
  12.         <C>
  13.             <C_ID>31</C_ID>
  14.             <C_NAME>Test_C2</C_NAME>
  15.         </C>
  16.     </B>
  17. </A>
  18. <A>
  19.     <A_ID>11</A_ID>
  20.     <A_NAME>Test_AA</A_NAME>
  21.     <B>
  22.         <B_ID>21</B_ID>
  23.         <B_NAME>Test_BB</B_NAME>
  24.         <C>
  25.             <C_ID>32</C_ID>
  26.             <C_NAME>Test_C3</C_NAME>
  27.         </C>
  28.         <C>
  29.             <C_ID>33</C_ID>
  30.             <C_NAME>Test_C4</C_NAME>
  31.         </C>
  32.     </B>
  33. </A>
  34. </ROOT>
Here's what I'm trying to achieve - bare with me...!

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
  1. output--
  2.     |
  3.     Test_A--
  4.         |
  5.         index.htm
  6.         Test_B--
  7.             |
  8.             index.htm
  9.     Test_AA--
  10.         |
  11.         index.htm
  12.         Test_BB--
  13.              |
  14.              index.htm
However, the attempt to create as described in 3) (i.e. HTML files stored in Test_B or Test_BB) results in the following error in Saxon:

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
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  3.  
  4. <xsl:output method="text"/>
  5. <xsl:output method="html" indent="yes" name="html"/>
  6.  
  7. <xsl:template match="/">
  8.     <xsl:for-each select="//A">
  9.         <xsl:variable name="filename" select="concat('output/',A_NAME,'/index.htm')" />
  10.         <xsl:value-of select="$filename" />
  11.         <xsl:result-document href="{$filename}" format="html">
  12.             <html>
  13.                 <head>
  14.                     <meta http-equiv="Content-Language" content="en" />
  15.                     <meta http-equiv="Content-Type" content="text/html; charset=windows-1252" />
  16.                     <title><xsl:value-of select="A_NAME"/></title>
  17.                     <link rel="StyleSheet" href="../style.css" type="text/css"></link>
  18.                 </head>                
  19.                 <body>
  20.                     <h4>Criterion</h4>
  21.                     <hr />
  22.                     <h5>Criterion Name:</h5>
  23.                     <p><xsl:value-of select="A_NAME"/></p>
  24.                     <h5>Criterion ID:</h5>
  25.                     <p><xsl:value-of select="A_ID"/></p>
  26.                     <hr />
  27.                 </body>
  28.             </html>
  29.         </xsl:result-document>
  30.         <xsl:if test="A_NAME='Test_A'">
  31.             <xsl:variable name="filename" select="concat('output/Test_A/',B/B_NAME,'/index.htm')" />
  32.             <xsl:value-of select="$filename" />
  33.             <xsl:result-document href="{$filename}" format="html">
  34.                 <html>
  35.                     <head>
  36.                          <meta http-equiv="Content-Language" content="en" />
  37.                          <meta http-equiv="Content-Type" content="text/html; charset=windows-1252" />
  38.                          <title><xsl:value-of select="B/B_NAME"/></title>
  39.                          <link rel="StyleSheet" href="../../style.css" type="text/css"></link>
  40.                      </head>                
  41.                      <body>
  42.                         <h4>Sub-Criterion</h4>
  43.                          <hr />
  44.                          <h5>Sub-Criterion Name:</h5>
  45.                          <p><xsl:value-of select="B/B_NAME"/></p>
  46.                          <h5>Sub-Criterion ID:</h5>
  47.                         <p><xsl:value-of select="B/B_ID"/></p>
  48.                          <hr />
  49.                      </body>
  50.                  </html>
  51.             </xsl:result-document>
  52.         </xsl:if>
  53.         <xsl:if test="A_NAME='Test_AA'">
  54.             <xsl:variable name="filename" select="concat('output/Test_AA/',B/B_NAME,'/index.htm')" />
  55.             <xsl:value-of select="$filename" />
  56.             <xsl:result-document href="{$filename}" format="html">
  57.                 <html>
  58.                     <head>
  59.                          <meta http-equiv="Content-Language" content="en" />
  60.                          <meta http-equiv="Content-Type" content="text/html; charset=windows-1252" />
  61.                          <title><xsl:value-of select="B/B_NAME"/></title>
  62.                          <link rel="StyleSheet" href="../../style.css" type="text/css"></link>
  63.                      </head>                
  64.                      <body>
  65.                          <h4>Sub-Criterion</h4>
  66.                          <hr />
  67.                          <h5>Sub-Criterion Name:</h5>
  68.                          <p><xsl:value-of select="B/B_NAME"/></p>
  69.                          <h5>Sub-Criterion ID:</h5>
  70.                         <p><xsl:value-of select="B/B_ID"/></p>
  71.                          <hr />
  72.                      </body>
  73.                  </html>
  74.             </xsl:result-document>
  75.         </xsl:if>
  76.     </xsl:for-each>
  77.     <xsl:for-each select="//B">
  78.         <xsl:if test="B_NAME='Test_B'">
  79.             <xsl:variable name="filename" select="concat('output/Test_A/Test_B/',C/C_ID,'.htm')" />
  80.             <xsl:value-of select="$filename" />
  81.             <xsl:result-document href="{$filename}" format="html">
  82.                 <html>
  83.                     <head>
  84.                         <meta http-equiv="Content-Language" content="en" />
  85.                         <meta http-equiv="Content-Type" content="text/html; charset=windows-1252" />
  86.                         <title><xsl:value-of select="C/C_NAME"/></title>
  87.                     <link rel="StyleSheet" href="../style.css" type="text/css"></link>
  88.                     </head>                
  89.                     <body>
  90.                         <h4>Metric</h4>
  91.                         <hr />
  92.                         <h5>Metric Name:</h5>
  93.                         <p><xsl:value-of select="C/C_NAME"/></p>
  94.                         <h5>Metric ID:</h5>
  95.                         <p><xsl:value-of select="C/C_ID"/></p>
  96.                         <hr />
  97.                     </body>
  98.                 </html>
  99.             </xsl:result-document>
  100.         </xsl:if>
  101.         <xsl:if test="B_NAME='Test_BB'">
  102.             <xsl:variable name="filename" select="concat('output/Test_AA/Test_BB/',C/C_ID,'.htm')" />
  103.             <xsl:value-of select="$filename" />
  104.             <xsl:result-document href="{$filename}" format="html">
  105.                 <html>
  106.                     <head>
  107.                         <meta http-equiv="Content-Language" content="en" />
  108.                         <meta http-equiv="Content-Type" content="text/html; charset=windows-1252" />
  109.                         <title><xsl:value-of select="//METRIC_NAME"/></title>
  110.                         <link rel="StyleSheet" href="../style.css" type="text/css"></link>
  111.                     </head>                
  112.                     <body>
  113.                         <h4>Metric</h4>
  114.                         <hr />
  115.                         <h5>Metric Name:</h5>
  116.                         <p><xsl:value-of select="C/C_NAME"/></p>
  117.                         <h5>Metric ID:</h5>
  118.                         <p><xsl:value-of select="C/C_ID"/></p>
  119.                         <hr />
  120.                     </body>
  121.                     </html>
  122.             </xsl:result-document>
  123.         </xsl:if>
  124.     </xsl:for-each>
  125. </xsl:template>
  126.  
  127. </xsl:stylesheet>
Mar 15 '07 #1
5 3215
dorinbogdan
839 Expert 512MB
Welcome to TSDN...

I took a look at the code, without testing...
The error seems to be thrown on the following line with concat():
[html] <xsl:if test="B_NAME='Test_B'">
<xsl:variable name="filename" select="concat('output/Test_A/Test_B/',C/C_ID,'.htm')" />
[/html]

As it said, the concat does not accept multiple items.
In this case, (for Test_B) C/C_ID will return 2 nodes, as it appears in XML:
[html] <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>
[/html]

So, try to insert a for-each command to loop through C nodes too, and be sure to call concat() for just one node at a time.

I hope it helps.
Mar 15 '07 #2

So, try to insert a for-each command to loop through C nodes too, and be sure to call concat() for just one node at a time.

I hope it helps.
Many thanks Dorinbogdan. This, has indeed worked! I inserted a for-each command within an existing for-each to loop the C nodes:

Expand|Select|Wrap|Line Numbers
  1. <xsl:for-each select="//B">
  2.         <xsl:if test="B_NAME='Test_B'">
  3.             <xsl:for-each select="C">
  4.                 <xsl:variable name="filename" select="concat('output/Test_A/Test_B/',C_ID,'.htm')" />
  5.                 <xsl:value-of select="$filename" />
  6.                 <!-- Creating  -->
  7.                 <xsl:result-document href="{$filename}" format="html">
  8.                     <html>
  9.                         <head>
  10.                             <meta http-equiv="Content-Language" content="en" />
  11.                             <meta http-equiv="Content-Type" content="text/html; charset=windows-1252" />
  12.                             <title><xsl:value-of select="C_NAME"/></title>
  13.                         <link rel="StyleSheet" href="../style.css" type="text/css"></link>
  14.                         </head>                
  15.                         <body>
  16.                             <h4>Metric</h4>
  17.                             <hr />
  18.                             <h5>Metric Name:</h5>
  19.                             <p><xsl:value-of select="C_NAME"/></p>
  20.                             <h5>Metric ID:</h5>
  21.                             <p><xsl:value-of select="C_ID"/></p>
  22.                             <hr />
  23.                         </body>
  24.                     </html>
  25.                 </xsl:result-document>
  26.             </xsl:for-each>
  27.         </xsl:if>
  28.         <xsl:if test="B_NAME='Test_BB'">
  29.             <xsl:for-each select="C">
  30.                 <xsl:variable name="filename" select="concat('output/Test_AA/Test_BB/',C_ID,'.htm')" />
  31.                 <xsl:value-of select="$filename" />
  32.                 <!-- Creating  -->
  33.                 <xsl:result-document href="{$filename}" format="html">
  34.                     <html>
  35.                         <head>
  36.                                     <meta http-equiv="Content-Language" content="en" />
  37.                             <meta http-equiv="Content-Type" content="text/html; charset=windows-1252" />
  38.                             <title><xsl:value-of select="C_NAME"/></title>
  39.                             <link rel="StyleSheet" href="../style.css" type="text/css"></link>
  40.                         </head>                
  41.                         <body>
  42.                             <h4>Metric</h4>
  43.                             <hr />
  44.                             <h5>Metric Name:</h5>
  45.                             <p><xsl:value-of select="C_NAME"/></p>
  46.                             <h5>Metric ID:</h5>
  47.                             <p><xsl:value-of select="C_ID"/></p>
  48.                             <hr />
  49.                         </body>
  50.                         </html>
  51.                 </xsl:result-document>
  52.             </xsl:for-each>
  53.         </xsl:if>
  54.     </xsl:for-each>
I now have a further question - I'm not sure if I should post it here or create a new thread? The question is with regard to this same XSL, but on a totally different matter. New thread I think.
Mar 19 '07 #3
dorinbogdan
839 Expert 512MB
Glad to hear it is working....

Yes, feel free to start a new thread. This is better because other members could see easier the post.
Mar 19 '07 #4
dorinbogdan
839 Expert 512MB
Since the problem was solved I'll close this thread.
Mar 21 '07 #5
dorinbogdan
839 Expert 512MB
I re-open the thread in order to allow further comments or suggestions from other members or experts, as per adim request.
Mar 22 '07 #6

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

11 posts views Thread by Johnny Ooi | last post: by
3 posts views Thread by Blaise Garant | last post: by
2 posts views Thread by Paul Verbelen | last post: by
5 posts views Thread by John Gordon | last post: by
reply views Thread by leo001 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.