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

时间:2009-05-06 01:03:47

标签: xslt namespaces

当使用XSLT样式表将包含嵌入式XHTML(使用命名空间)的XML文件转换为纯XHTML时,我在最初为XHTML的元素上留下了冗余的命名空间定义。简单的测试用例:

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>元素中? (作为参考,我在Cygwin上使用xsltproclibxml2-2.7.3libxslt-1.1.24。)

2 个答案:

答案 0 :(得分:8)

而不是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>

答案 1 :(得分:4)

更新exclude-result-prefixes以包含默认命名空间:

exclude-result-prefixes="#default"

或者您可以通过执行以下操作来抑制所有内联命名空间:

exclude-result-prefixes="#all"

虽然有一些令人讨厌的东西,因为有些处理器期望以空格分隔的列表,而其他处理器则期望以逗号分隔的列表。 xsltproc似乎喜欢以逗号分隔,所以如果你仍想要明确,你可以这样做:

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