首页 > 解决方案 > 对文字结果元素和元素构造函数方法使用单个命名空间声明

问题描述

给定 XML 源

<Content>
</Content>

和转型:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
  office:version="1.0"
  xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
  xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0">

  <xsl:output indent="yes" encoding="UTF-8"/>
  <xsl:template match="Content">
    <xsl:element name="office:document">
      <xsl:attribute name="office:version">1.2</xsl:attribute>
      <xsl:attribute name="office:mimetype">application/vnd.oasis.opendocument.text</xsl:attribute>

      <xsl:element name="office:body">
        <xsl:element name="office:text">
          <xsl:element name="text:p">Hello world.
          </xsl:element>
          <xsl:element name="text:p">Goodbye world.
          </xsl:element>
        </xsl:element>
      </xsl:element>

    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

结果

<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
                 office:version="1.2"
                 office:mimetype="application/vnd.oasis.opendocument.text">
   <office:body>
      <office:text>
         <text:p xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0">Hello world.
          </text:p>
         <text:p xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0">Goodbye world.
          </text:p>
      </office:text>
   </office:body>
</office:document>

段落元素的命名空间是重复的。我希望它应用于根元素以避免这种情况,就像 odf 文件中的规范一样。

但是,如果我将名称空间添加到根元素,XSL 将包含冗余名称空间声明,用于电子表格和根元素。如果我随后从样式表元素中删除名称空间,我将无法在这些名称空间中添加文字结果元素。

我在 Kay 的第 4 版参考文献 p473 中读到“避免重复的命名空间声明完全是 XSLT 序列化程序的工作。”但我无法利用这种洞察力来产生所需的结果。

标签: xslt-2.0xml-namespaces

解决方案


对于包含的示例,您将获得包含的结果,因为生成的元素xsl:element在您在样式表元素中声明的范围内没有任何名称空间,它们仅用于在某个名称空间中创建元素。从该示例中不清楚为什么您需要xsl:element并且不能简单地使用文字结果元素。

如果您确实需要使用 构造根元素xsl:element,则可以使用 构造名称空间节点<xsl:namespace name="text" select="'urn:oasis:names:tc:opendocument:xmlns:text:1.0'"/>。请参阅https://xsltfiddle.liberty-development.net/jyH9rMg以获取在线示例,该示例使用

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
  office:version="1.0"
  xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
  xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0">

  <xsl:output indent="yes" encoding="UTF-8"/>
  <xsl:template match="Content">
    <xsl:element name="office:document">
      <xsl:namespace name="text" select="'urn:oasis:names:tc:opendocument:xmlns:text:1.0'"/>
      <xsl:attribute name="office:version">1.2</xsl:attribute>
      <xsl:attribute name="office:mimetype">application/vnd.oasis.opendocument.text</xsl:attribute>

      <xsl:element name="office:body">
        <xsl:element name="office:text">
          <xsl:element name="text:p">Hello world.
          </xsl:element>
          <xsl:element name="text:p">Goodbye world.
          </xsl:element>
        </xsl:element>
      </xsl:element>

    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

进入

<office:document xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
                 xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
                 office:version="1.2"
                 office:mimetype="application/vnd.oasis.opendocument.text">
   <office:body>
      <office:text>
         <text:p>Hello world.
          </text:p>
         <text:p>Goodbye world.
          </text:p>
      </office:text>
   </office:body>
</office:document>

推荐阅读