4

What I am doing: I am trying to transform xml to html using xslt.


Question: The program is executing without any error, it is gproducing the output file also, but it does not transform the xml to html. My guess is that the for loop in the xsl is not fetching the data.


XSLTTest.java

 package JavaXSLTExample;
import javax.xml.transform.ErrorListener;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
public class XSLTTest {
public static void main(String[] args)
{
    /*if (args.length != 3)
    {
        System.err.println("give command as follows : ");
        System.err.println("XSLTTest data.xml converted.xsl converted.html");
        return;
    }*/
    String dataXML = "C:\\Users\\Devrath\\Desktop\\XSL\\FileOne.xml";
    String inputXSL = "C:\\Users\\Devrath\\Desktop\\XSL\\FileTwo.xsl";
    String outputHTML = "C:\\Users\\Devrath\\Desktop\\XSL\\output1.html";

    XSLTTest st = new XSLTTest();
    try
    {
        st.transform(dataXML, inputXSL, outputHTML);
    }
    catch (TransformerConfigurationException e)
    {
        System.err.println("TransformerConfigurationException");
        System.err.println(e);
    }
    catch (TransformerException e)
    {
        System.err.println("TransformerException");
        System.err.println(e);
    }
    }

    public void transform(String dataXML, String inputXSL, String outputHTML)
    throws TransformerConfigurationException,
    TransformerException
    {
        TransformerFactory factory = TransformerFactory.newInstance();
        StreamSource xslStream = new StreamSource(inputXSL);
        Transformer transformer = factory.newTransformer(xslStream);
        StreamSource in = new StreamSource(dataXML);
        StreamResult out = new StreamResult(outputHTML);
        transformer.transform(in, out);
        System.out.println("The generated HTML file is:" + outputHTML);
    }
}

FileOne.xml

<languages-list>
  <language>
    <name>Kannada</name>
    <region>Karnataka</region>
    <users>38M</users>
  <family>Dravidian</family>
  </language>
  <language>
    <name>Telugu</name>
    <region>Andra Pradesh</region>
    <users>74M</users>
    <family>Dravidian</family>
  </language>
  <language>
    <name>Tamil</name>
    <region>TamilNadu</region>
    <users>61M</users>
    <family>Dravidian</family>
  </language>
  <language>
    <name>Malayalam</name>
    <region>Kerela</region>
    <users>33M</users>
    <family>Dravidian</family>
  </language>
  <language>
    <name>Hindi</name>
    <region>Andaman and Nicobar Islands, North india, Parts of North east</region>
    <users>442M</users>
    <family>Indo Aryan</family>
  </language>
  <language>
    <name>Assamese</name>
    <region>Assam, Arunachal Pradesh</region>
    <users>13M</users>
    <family>Indo Aryan</family>
  </language>
</languages-list>

FileTwo.xsl

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="/">
        <html>
            <body>
                <h1>Indian Languages details</h1>
                <table border="1">
                    <tr>
                        <th>Language</th>
                        <th>Family/Origin</th>
                        <th>No. of speakers</th>
                        <th>Region</th>
                    </tr>
         <xsl:for-each select="language-list/language">
                    <tr>
                        <td><xsl:value-of select="name"/></td>
                        <td><xsl:value-of select="family"/></td>
                        <td><xsl:value-of select="users"/></td>
                        <td><xsl:value-of select="region"/></td>
                    </tr>
                 </xsl:for-each>
                </table>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet> 

Output.html

<html>
<body>
<h1>Indian Languages details</h1>
<table border="1">
<tr>
<th>Language</th><th>Family/Origin</th><th>No. of speakers</th><th>Region</th>
</tr>
</table>
</body>
</html>
Don Roby
  • 40,677
  • 6
  • 91
  • 113
Devrath
  • 42,072
  • 54
  • 195
  • 297
  • 5
    Come on ... You start your XML with the root element "languages-list" but then you refer to "language-list" in your XSLT ?! – Seelenvirtuose Jan 27 '14 at 12:17
  • 3
    You might like to know that with schema-aware XSLT 2.0, that trivial error might have been caught for you at compile time. – Michael Kay Jan 27 '14 at 19:57

2 Answers2

14

XML is very unforgiving. This:

     <xsl:for-each select="language-list/language">

needs to be:

     <xsl:for-each select="languages-list/language">
michael.hor257k
  • 113,275
  • 6
  • 33
  • 51
0

Just fixing language(s)-list does not make the program error free. It fails with error as below:

Error on line 7 of FileTwo.xsl:
  java.lang.IllegalArgumentException: URI scheme is not "file"
TransformerException
net.sf.saxon.trans.XPathException: java.lang.IllegalArgumentException: URI scheme is not "file"

This is misleading because it does not point to the actual problem. The problem is with "outputHTML" it should be of a type File or FileOutputStream.

I have tried with File and it worked. So this statement:

StreamResult out = new StreamResult(outputHTML);

is rewritten as:

StreamResult out = new StreamResult(new File(outputHTML));

Ofcourse import java.io.File

Using FileOutputStream needs appropriate code tweaking and import statements.