2014-09-09 2 views
0

Я сделал минимальный пример, чтобы воспроизвести проблему. Это преобразование (mini.xsl):java copy-of xsl transform удаляет префикс пространства имен

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="/"> 
     <foo> 
      <xsl:copy-of select="."/> 
     </foo> 
    </xsl:template> 
</xsl:stylesheet> 

и это вход (mini.xml):

<?xml version="1.0" encoding="utf-8"?> 
<bar xmlns:x="baz"> 
    <x:baz/> 
</bar> 

Когда я применить преобразование с

xsltproc mini.xsl mini.xml 

Результат выглядит как ожидалось:

<?xml version="1.0"?> 
<foo> 
    <bar xmlns:x="baz"> 
    <x:baz/> 
    </bar> 
</foo> 

Ho Веверу, когда я бегу преобразование с помощью следующей программы Java,

import java.io.FileInputStream; 
import java.io.IOException; 

import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.parsers.ParserConfigurationException; 
import javax.xml.transform.Result; 
import javax.xml.transform.Source; 
import javax.xml.transform.Templates; 
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 javax.xml.transform.stream.StreamSource; 

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

public class Program 
{ 
    public static void main(String[] args) 
    { 
     try 
     { 
      Source transform = new StreamSource(new FileInputStream(args[0])); 

      Templates templates = TransformerFactory.newInstance().newTemplates(transform); 

      Document input = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new FileInputStream(args[1])); 

      Result result = new StreamResult(System.out);   

      templates.newTransformer().transform(new DOMSource(input), result); 
     } 
     catch (TransformerFactoryConfigurationError | ParserConfigurationException | SAXException | IOException | TransformerException e) 
     { 
      e.printStackTrace(); 
     } 
    } 
} 

результат выглядит следующим образом:

<?xml version="1.0" encoding="UTF-8"?> 
<foo> 
    <bar xmlns:x="baz"> 
    <baz/> 
    </bar> 
</foo> 

(обратите внимание, что х:. префикс перед БАЗ отсутствует)

Почему?

И что я могу с этим сделать (чтобы сохранить префикс пространства имен)?

ответ

1

Для того, что я могу предположить, являются историческими причинами, DocumentBuilderFactory является по умолчанию без имени пространства. Вам необходимо явно включить пространства имен, прежде чем вы сделаете newDocumentBuilder().

Было бы лучше использовать parse метод, который принимает File непосредственно, а не создавать свои собственные FileInputStream (что ваш код не закрывается, как только синтаксический анализ завершен), а также с StreamSource из которых Transformer построен ,

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
dbf.setNamespaceAware(true); 
Document input = dbf.newDocumentBuilder().parse(new File(args[1])); 
+2

Лучше все же передать StreamSource в метод transform() вместо DOM. DOM и XSLT на самом деле не так хорошо сочетаются, и большинство процессоров XSLT будут работать намного лучше, если вы разрешите им самим строить дерево. –

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