如何从XSLT样式表中防止这些冗余名称空间?

问题描述:

当使用XSLT样式表将包含嵌入式XHTML的XML文件(使用名称空间)转换为纯XHTML时,剩下的元素最初是XHTML的冗余名称空间定义。简单的测试用例:如何从XSLT样式表中防止这些冗余名称空间?

XML:

<?xml version="1.0" encoding="utf-8" ?> 
<?xml-stylesheet type="text/xml" href="fbb.xsl"?> 
<foo xmlns="urn:foo:bar:baz" xmlns:html="http://www.w3.org/1999/xhtml"> 
    <bar> 
     <baz>Some <html:i>example</html:i> text.</baz> 
    </bar> 
</foo> 

XSL:

<?xml version="1.0" encoding="utf-8" ?> 
<xsl:stylesheet version="1.0" xmlns="http://www.w3.org/1999/xhtml" xmlns:fbb="urn:foo:bar:baz" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="fbb"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="/fbb:foo"> 
     <html> 
      <head> 
       <title>Example</title> 
      </head> 

      <body> 
       <p> 
        <xsl:copy-of select="fbb:bar/fbb:baz/node()"/> 
       </p> 
      </body> 
     </html> 
    </xsl:template> 
</xsl:stylesheet> 

输出:

<?xml version="1.0"?> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
    <title>Example</title> 
    </head> 
    <body> 
    <p>Some <html:i xmlns="urn:foo:bar:baz" xmlns:html="http://www.w3.org/1999/xhtml">example</html:i> text.</p> 
    </body> 
</html> 

是否可以防止冗余的命名空间(和前缀)被添加到<i>元素? (仅供参考,我使用xsltproclibxml2-2.7.3libxslt-1.1.24在Cygwin。)

代替xsl:copy-of使用身份转换模板和XHTML元素删除命名空间前缀。

<xsl:stylesheet version="1.0" 
       xmlns="http://www.w3.org/1999/xhtml" 
       xmlns:fbb="urn:foo:bar:baz" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:html="http://www.w3.org/1999/xhtml" 
       exclude-result-prefixes="fbb html"> 

    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="/fbb:foo"> 
    <html> 
     <head> 
     <title>Example</title> 
     </head> 
     <body> 
     <p> 
      <xsl:apply-templates select="fbb:bar/fbb:baz/node()"/> 
     </p> 
     </body> 
    </html> 
    </xsl:template> 

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

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

</xsl:stylesheet> 

更新您的exclude-result-prefixes包括默认的命名空间:

exclude-result-prefixes="#default" 

或者,你可以通过做抑制所有内嵌命名空间:

exclude-result-prefixes="#all" 

尽管如此,有些处理器期望一个空格分隔的列表,而另一些处理器期望逗号分隔的列表。 xsltproc的似乎很喜欢用逗号分隔的,所以如果你还是想明确的,你可以这样做:

exclude-result-prefixes="#default,fbb" 
+1

嗯......我的xsltproc副本实际上为逗号分隔的列表提供了一个“未定义的命名空间”错误。包含“#default”的空格分隔列表似乎没有改变它的行为,并且包括“#all”再次产生“未定义的名字空间”。 – 2009-05-06 16:30:59