【问题标题】:How can I prevent these redundant namespaces from an XSLT stylesheet?如何从 XSLT 样式表中防止这些冗余名称空间?
【发布时间】:2009-05-06 01:03:46
【问题描述】:

当使用 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>

是否可以防止将多余的命名空间(和前缀)添加到&lt;i&gt; 元素中? (作为参考,我在 Cygwin 上使用 xsltproclibxml2-2.7.3libxslt-1.1.24。)

【问题讨论】:

    标签: xslt namespaces


    【解决方案1】:

    使用身份转换模板代替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>
    

    【讨论】:

      【解决方案2】:

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

      exclude-result-prefixes="#default"
      

      或者您可以通过以下方式抑制所有内联命名空间:

      exclude-result-prefixes="#all"
      

      虽然有一点点不稳定,因为一些处理器需要一个空格分隔的列表,而另一些处理器则需要一个逗号分隔的列表。 xsltproc 似乎喜欢逗号分隔,所以如果你仍然想明确,你可以这样做:

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

      【讨论】:

      • 嗯……我的 xsltproc 副本实际上给出了逗号分隔列表的“未定义命名空间”错误。包含“#default”的空格分隔列表似乎不会改变其行为,并且包含“#all”再次产生“未定义的命名空间”。
      • libxslt 仅支持 XSLT 1.0 和 #default 和 #all 都是 XSLT 2.0。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-13
      相关资源
      最近更新 更多