2016-11-22 2 views
2

Я пытаюсь использовать Java Transformer с org.w3c.dom.Document для ввода, вывода и XSLT. К сожалению, выход равен входу XSLT. Поэтому кажется, что преобразование не используется правильно. Я не мог найти причины для такого поведения, поэтому я прошу его здесь и надеюсь на помощь.JAVA Transformation возвращает 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); 

на DocumentBuilderFactory при работе с XSLT (как для таблиц стилей, а также входных документов, если вы создаете их как DOM документов, в общем-то легче и более эффективно просто работать с StreamSource, если вы хотите загрузить файлы XML и/или XSLT в качестве файлов).

+0

Большое спасибо. Вот почему! – nikmaster

+1

Я не видел этого раньше, так что спасибо! Но я бы добавил всадника: нет оснований строить таблицу стилей в форме DOM, если вы не собираетесь манипулировать ею в Java-коде, который нуждается в интерфейсах DOM. Поставляйте его как StreamSource. –

+0

@MichaelKay, я соглашаюсь на «StreamSource», но, поскольку плакат предоставил некоторый тестовый пример, кажется, с использованием 'org.w3c.dom.Document', я сосредоточился на исправлении этого кода. –

 Смежные вопросы

  • Нет связанных вопросов^_^