我试图从文档中剥离名称空间限定符,同时将文档名称空间保留为默认值:
<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>
我怎样才能做到这一点?
解决方法:
如果您希望输出保留“ 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>