java copy-of xsl transformation删除名称空间前缀

时间:2014-09-09 14:05:03

标签: java xml xslt

我做了一个简单的例子来重现这个问题。这是转换(mini.xsl):

<?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>

但是,当我使用以下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>

(注意缺少baz前面的x:前缀。)

为什么?

我该怎么办呢(保留命名空间前缀)?

1 个答案:

答案 0 :(得分:1)

我只能假设是历史原因,默认情况下DocumentBuilderFactory 非命名空间感知。在执行newDocumentBuilder()之前,您需要明确地切换命名空间。

最好使用直接占用parse的{​​{1}}方法,而不是创建自己的File(解析完成后代码不会关闭),同样使用构建FileInputStream的{​​{1}}。

StreamSource
相关问题