如何强制XSLT结果树使用特定的默认命名空间进行序列化?

时间:2009-08-16 14:42:37

标签: java xml xslt xpath

我正在尝试从文档中删除命名空间限定符,同时将文档命名空间保留为默认名称:

<foo:doc xmlns:foo='somenamespace'>
    <foo:bar />
</foo:doc>

<doc xmlns='somenamespace'>
    <bar/>
</doc>

(我知道,这没有意义,但是我们的客户端没有获取XML并使用字符串比较来查找文档中的信息。)

我正在使用Java的JAXP Transformer API来完成我的工作。我可以使用此样式表删除所有命名空间信息,但我想强制不带前缀的序列化:

<?xml version='1.0' encoding='UTF-8'?> 
    <xsl:stylesheet 
          xmlns:xsl='http://www.w3.org/1999/XSL/Transform'  
          xmlns:xs='http://www.w3.org/2001/XMLSchema' 
          exclude-result-prefixes='xs' 
          version='2.0'> 

      <xsl:output omit-xml-declaration='yes' indent='yes'/>

      <xsl:template match='@*|node()'> 
        <xsl:copy> 
          <xsl:apply-templates select='@*|node()' /> 
        </xsl:copy> 
      </xsl:template> 

      <xsl:template match='*'> 
        <xsl:element name='{local-name()}'> 
          <xsl:apply-templates select='@*|node()' /> 
        </xsl:element> 
      </xsl:template> 
</xsl:stylesheet>

我该怎么做?

2 个答案:

答案 0 :(得分:2)

如果希望输出保留“somenamespace”命名空间,但元素上没有命名空间前缀,请在样式表中的未命名命名空间(不带前缀)中声明“somenamenamespace”: xmlns ='somenamespace “

然后使用local-name()创建的元素将具有该命名空间,但不具有命名空间前缀:

<doc xmlns="somenamespace">
    <bar/>
</doc>

当您执行关于模糊规则匹配的样式表时,您是否看到警告? “node()”和“*”的模板匹配都会触发元素的匹配。

node()是指定的快捷方式:“* | text()| comment()| processing-instruction()”

你应该做两件事之一来解决模棱两可的比赛:

1。)更改“@ * | node()”的模板匹配,通过显式匹配其他节点类型来排除元素。

<?xml version='1.0' encoding='UTF-8'?> 
<xsl:stylesheet 
    xmlns:xsl='http://www.w3.org/1999/XSL/Transform'  
    xmlns:xs='http://www.w3.org/2001/XMLSchema' 
    xmlns='somenamespace'
    exclude-result-prefixes='xs' 
    version='2.0'> 

    <xsl:output omit-xml-declaration='yes' indent='yes'/>

    <xsl:template match='@*|text()|comment()|processing-instruction()'> 
        <xsl:copy> 
            <xsl:apply-templates select='@*|node()' /> 
        </xsl:copy> 
    </xsl:template> 

    <xsl:template match='*' > 
        <xsl:element name='{local-name()}'> 
            <xsl:apply-templates select='@*|node()' /> 
        </xsl:element> 
    </xsl:template> 

</xsl:stylesheet>

2.)将优先级属性添加到“”的模板匹配中,这会突破优先级匹配并确保调用它以支持“@ | node()”。

<?xml version='1.0' encoding='UTF-8'?> 
<xsl:stylesheet 
    xmlns:xsl='http://www.w3.org/1999/XSL/Transform'  
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    xmlns='somenamespace' 
    exclude-result-prefixes='xs' 
    version='2.0'> 

    <xsl:output omit-xml-declaration='yes' indent='yes'/>

    <xsl:template match='@*|node()'> 
        <xsl:copy> 
            <xsl:apply-templates select='@*|node()' /> 
        </xsl:copy> 
    </xsl:template> 

    <xsl:template match='*' priority="1"> 
        <xsl:element name='{local-name()}'> 
            <xsl:apply-templates select='@*|node()' /> 
        </xsl:element> 
    </xsl:template> 

</xsl:stylesheet>

答案 1 :(得分:2)

不是您想要的模板匹配“sn:*”而不是“*”而且

<xsl:namespace-alias stylesheet-prefix="sn" result-prefix="#default"/>

另外? (假设你有xslns:sn =“somenamespace”)