javax.xml.transform.Transformer忽略前缀?

时间:2013-02-13 04:34:55

标签: java xml xslt

我试图解析一个非常简单的例子:

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:openSearch='http://a9.com/-/spec/opensearch/1.1/'>
    <openSearch:totalResults>100</openSearch:totalResults>
</root>

我使用的样式表如下:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                version="1.0" 
                xmlns:app='http://www.w3.org/2007/app' >
<xsl:output method="xml" indent="yes"/>
<xsl:preserve-space elements="*"/>
<xsl:template match="/">
    <results>
        <xsl:attribute name="total-results">
                <xsl:value-of 
                 select="atom:root/openSearch:totalResults"/>
        </xsl:attribute>
    </results>
</xsl:template>
</xsl:stylesheet>

这适用于libxslt,没问题。我现在尝试在java中执行相同的任务,我正在尝试使用javax.xml.transform包来执行此操作。它不是预期的结果,而是为total-results属性提供一个空值。但是当我将值改为:

                <xsl:value-of select="root/totalResults"/>

有效。更改xml和xslt不是一个选项。我应该在某个地方设置一个参数吗?代码非常简单:

InputSource xmlSource = new InputSource( new StringReader(xml) );

DocumentBuilder builder = factory.newDocumentBuilder();
document = builder.parse(xmlSource);

// Use a Transformer for output
TransformerFactory tFactory = TransformerFactory.newInstance();


StreamSource stylesource = new StreamSource(new StringReader(styleSheet));
Transformer transformer = tFactory.newTransformer(stylesource);

StringWriter writer = new StringWriter();

DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(writer);
transformer.transform(source, result);

stringResult = writer.toString();

1 个答案:

答案 0 :(得分:5)

在样式表中,您缺少“atom”和“openSearch”的名称空间声明。 以下作品:

  1. 在样式表
  2. 中添加“openSearch”命名空间(从xml复制)
  3. 删除“atom”命名空间,因为没有相关信息 命名空间
  4. 将工厂设置为名称空间感知:factory.setNamespaceAware(true);
  5. 这是Scala中的完整代码(抱歉,我懒得从文件解析xml和样式表或在Java中进行字符串连接):

      def testxsl = {
          val xml = """<?xml version="1.0" encoding="UTF-8"?>
    <root xmlns:openSearch='http://a9.com/-/spec/opensearch/1.1/'>
        <openSearch:totalResults>100</openSearch:totalResults>
    </root>
          """
          val styleSheet = """<?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
            xmlns:app='http://www.w3.org/2007/app' 
            xmlns:openSearch='http://a9.com/-/spec/opensearch/1.1/'>
    <xsl:output method="xml" indent="yes"/>
    <xsl:preserve-space elements="*"/>
    <xsl:template match="/">
        <results>
            <xsl:attribute name="total-results">
                    <xsl:value-of select="root/openSearch:totalResults"/>
            </xsl:attribute>
        </results>
    </xsl:template>
    </xsl:stylesheet>
            """
        val xmlSource = new InputSource( new StringReader(xml) );
        val factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        val builder = factory.newDocumentBuilder();
        val document = builder.parse(xmlSource);
    
        // Use a Transformer for output
        val tFactory = TransformerFactory.newInstance();
    
    
        val stylesource = new StreamSource(new StringReader(styleSheet));
        val transformer = tFactory.newTransformer(stylesource);
    
        val writer = new StringWriter();
    
        val source = new DOMSource(document);
        val result = new StreamResult(writer);
        transformer.transform(source, result);
        writer.toString(); 
      }