Renjith
Renjith

Reputation: 1154

XML Transformation using DOMSource, DOMResult & XSLT

I am trying to transform the following XML

 <PHONEBOOK>
    <PERSON>
        <NAME>Ren1</NAME>
        <EMAIL>[email protected]</EMAIL>
        <TELEPHONE>999-999-9999</TELEPHONE>
        <WEB>www.ren1.com</WEB>
    </PERSON>
    <PERSON>
        <NAME>Ren2</NAME>
        <EMAIL>[email protected]</EMAIL>
        <TELEPHONE>999-999-9999</TELEPHONE>
        <WEB>www.ren2.com</WEB>
    </PERSON>
    <PERSON>
        <NAME>Ren3</NAME>
        <EMAIL>[email protected]</EMAIL>
        <TELEPHONE>999-999-9999</TELEPHONE>
        <WEB>www.ren3.com</WEB>
    </PERSON>
</PHONEBOOK>

to

<Names><Name>Ren1</Name><Name>Ren2</Name><Name>Ren3</Name></Names>

using DOMSource, DOMResult and XSLT.

XSLT used is as follows

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:output omit-xml-declaration="yes" method="xml"></xsl:output>

    <xsl:template match="/">

        <Names>
            <xsl:for-each select="PHONEBOOK/PERSON">
                <Name>

                    <xsl:value-of select="NAME" />
                </Name>
            </xsl:for-each>
        </Names>

Java Code used for transformation:

package test1;

import java.io.IOException;
import java.io.StringWriter;
import java.io.ObjectInputStream.GetField;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

public class Test2 {
    public static void main(String[] args) throws TransformerException,
            ParserConfigurationException, SAXException, IOException {
        // TODO Auto-generated method stub

        //Stylesheet
        StreamSource stylesource = new StreamSource(
                "src/test1/transform_stylesheet1.xsl");

        DocumentBuilderFactory docbFactory = DocumentBuilderFactory
                .newInstance();
        DocumentBuilder dBuilder = docbFactory.newDocumentBuilder();

        //source XML
        Document sourceDoc = dBuilder.parse("src/test1/Sample1.xml");

        DOMSource source = new DOMSource(sourceDoc);

        TransformerFactory transformerFactory = TransformerFactory
                .newInstance();
        Transformer transformer = transformerFactory
                .newTransformer(stylesource);

        Document document = dBuilder.newDocument();
        DOMResult result = new DOMResult(document);

        transformer.transform(source, result);

        Node resultDoc = ((Document) result.getNode()).getDocumentElement();

        System.out.println(resultDoc.getChildNodes().getLength());

        // print the result
        StringWriter writer = new StringWriter();
        transformer.transform(new DOMSource(resultDoc), new StreamResult(writer));
        String str = writer.toString();
        System.out.println(str);


    }
}

Output of the above is as follows:

3 <Names/>

but i expect,

3
<Names><Name>Ren1</Name><Name>Ren2</Name><Name>Ren3</Name></Names>

i debugged the code and found that 'resultDoc' has the content which i expect. Am i missing something while printing the result?

Upvotes: 3

Views: 5152

Answers (1)

Glorfindel
Glorfindel

Reputation: 22651

Your problem is that you're using the same transformer for the stylesheet processing and the output. That means, the stylesheet is applied again, but this time to the <Names><Name>Ren1</Name>...</Names> xml. You can imagine that this doesn't give the results you want.

Change your code to:

// print the result
StringWriter writer = new StringWriter();
Transformer transformer2 = transformerFactory.newTransformer();
transformer2.transform(new DOMSource(resultDoc), new StreamResult(writer));
String str = writer.toString();
System.out.println(str);

and it should work.

As @Abel mentions, you can also do the stylesheet processing and the to String in one go:

StringWriter writer = new StringWriter();
transformer.transform(source, new StreamResult(writer));
String str = writer.toString();
System.out.println(str);

You don't need the DOMResult and DOMSource variables then.

Upvotes: 4

Related Questions