2016-11-22 78 views
2

我尝试使用带有org.w3c.dom.Document的Java Transformer作为输入,输出和XSLT。不幸的是,输出等于XSLT输入。所以看起来转换没有被正确使用。我无法找到任何这种行为的原因,所以我在这里问,希望得到帮助。JAVA转换返回XSLT而不是转换结果

我的代码:

import java.io.BufferedReader; 
import java.io.FileReader; 

import java.io.IOException; 
import java.io.StringReader; 
import java.io.StringWriter; 
import java.io.Writer; 
import java.sql.SQLException; 

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.TransformerFactoryConfigurationError; 
import javax.xml.transform.dom.DOMSource; 
import javax.xml.transform.stream.StreamResult; 

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

public class XMLTransform { 
    public static void main(String[] args) { 

     StringWriter stringWriter = null; 
     try { 
      // Read Input Files 
      Document xslt = parseXML(readFile("...")); // link to XSLT 
      Document input = parseXML(readFile("...")); // link to input 

      // Create new Transformer with the XSLT 
      TransformerFactory factory = TransformerFactory.newInstance(); 
      Transformer transformer = factory.newTransformer(new DOMSource(xslt)); 

      // create variables for the output 
      stringWriter = new StringWriter(); 
      StreamResult streamResult = new StreamResult(stringWriter); 

      // transform 
      transformer.transform(new DOMSource(input), streamResult); 

      // parse it to XML DOM File 
      Document resultXML = parseXML(stringWriter.toString()); 

      // output, so we see it is wrong 
      System.out.println(convertDocumentToString(resultXML)); 
     } catch (Exception e) { 
     } finally { 
      try { 
       if (stringWriter != null) stringWriter.close(); 
      } catch (Exception e1) { }; 
     } 
    } 

    ////////////////////////////////////// 
    //Helper-Methods which seems to work// 
    ////////////////////////////////////// 

    public static String convertDocumentToString(Document doc) throws TransformerFactoryConfigurationError, 
      TransformerException { 
     Transformer tf = TransformerFactory.newInstance().newTransformer(); 
     tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); 
     tf.setOutputProperty(OutputKeys.INDENT, "yes"); 
     Writer out = new StringWriter(); 
     tf.transform(new DOMSource(doc), new StreamResult(out)); 
     return out.toString(); 
    } 

    private static Document parseXML(String str) throws ParserConfigurationException, SAXException, IOException, 
      SQLException { 
     DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
     DocumentBuilder builder = factory.newDocumentBuilder(); 
     return builder.parse(new InputSource(new StringReader(str))); 
    } 

    private static String readFile(String filename) throws Exception { 
     BufferedReader br = new BufferedReader(new FileReader(filename)); 
     try { 
      StringBuilder sb = new StringBuilder(); 
      String line = br.readLine(); 

      while (line != null) { 
       sb.append(line); 
       line = br.readLine(); 
      } 
      return sb.toString(); 
     } finally { 
      br.close(); 
     } 
    } 
} 

我用下面的输入文件:

XSLT:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 

    <xsl:template match="/"> 
    <xsl:apply-templates select="/Test/Content"/> 
    </xsl:template> 

    <xsl:template match="/Test/Content"> 
      <xsl:copy-of select="." /> 
    </xsl:template> 
</xsl:stylesheet> 

输入,文件:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<Test> 
    <Content> 
    <X>x</X> 
    <Y>y</Y> 
    <Z>z</Z> 
    </Content> 
    <Template> 
    <Definition> 
     <A>A</A> 
     <B>B</B> 
     <C>C</C> 
    </Definition> 
    </Template> 
</Test> 

而且我得到的奇怪输出(等于XSLT)

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
<xsl:output encoding="UTF-8" indent="yes" method="xml" version="1.0"/> 
<xsl:template match="/"> 
<xsl:apply-templates select="/Test/Content"/> 
</xsl:template> 
<xsl:template match="/Test/Content"> 
<xsl:copy-of select="."/> 
</xsl:template> 
</xsl:stylesheet> 

有谁知道,为什么输出等于XSLT文件,以及如何解决它?这样才能返回正确的转换XML?

感谢

回答

4

要确保你

factory.setNamespaceAware(true); 
用XSLT工作时

DocumentBuilderFactory(无论是样式表,以及输入文档,如果您创建为DOM文档;通常更容易如果要将XML和/或XSLT加载为文件,则可以更简单地使用StreamSource)。

+0

非常感谢。这就是原因! – nikmaster

+1

我以前没有见过这样的人,所以谢谢!但是我会添加一个骑手:除非要在需要DOM接口的Java代码中操作它,否则没有任何理由以DOM的形式提供样式表。以StreamSource的形式提供。 –

+0

@MichaelKay,我同意'StreamSource',但是由于海报提供了一些测试用例,它似乎使用了'org.w3c.dom.Document',我专注于修复该代码。 –