使用XSLT <xsl:element>和字面声明元素有什么区别?</xsl:element>

时间:2012-09-24 16:16:33

标签: xml xslt

我最近刚开始使用XSLT,并且想知道使用<xsl:element>定义元素与在XSLT中将它们声明为文字之间的有效区别。例如,让我们简化一个案例,我将一个小型XML文档的内容转换为(x)HTML。

1.我可以使用<xsl:element>方式:

<xsl:element name="h1">
    <xsl:value-of select="heading"/>
</xsl:element>

2。或者手动定义元素:

<h1>
    <xsl:value-of select="heading"/>
</h1>

这两者之间的实际差异是什么,如果存在差异,哪些被认为是'good-style'

4 个答案:

答案 0 :(得分:6)

它们几乎完全相同,例外是文字<h1>元素将向结果树添加样式表中该范围内的命名空间节点,而<xsl:element name="h1">不会。这与输出的不同之处取决于样式表包含的命名空间声明的确切位置以及结果树中使用它们的位置(如果有的话)。例如,针对任何输入XML文档运行以下转换:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:foo="http://example.com">

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

  <xsl:template match="/">
    <root>
      <foo:element1 />
      <foo:element2 />
    </root>
  </xsl:template>
</xsl:stylesheet>

产生以下输出(使用xsltproc):

<?xml version="1.0"?>
<root xmlns:foo="http://example.com">
  <foo:element1/>
  <foo:element2/>
</root>

但是将样式表中的文字<root>更改为<xsl:element name="root">会生成

<?xml version="1.0"?>
<root>
  <foo:element1 xmlns:foo="http://example.com"/>
  <foo:element2 xmlns:foo="http://example.com"/>
</root>

因为<xsl:element>表单未将“foo”命名空间节点附加到生成的元素。如果这很重要,并且您实际上想要将样式表命名空间声明复制到使用<xsl:element>创建的元素上,则可以通过嵌套类似

的内容来实现
<xsl:copy-of select="document('')/*/namespace::foo" />

直接在其中(使用document('')的成语,提供对样式表XML文档本身的访问)。

但一般来说,<xsl:element>的主要用途是计算元素名称而不是“编译时”字面值。

答案 1 :(得分:4)

xsl:element允许定义在编写样式表时不知道名称的元素,以及动态创建名称的元素。如果可能的话,我总是使用内联定义(即手动)。它更短,我认为它更具可读性。

答案 2 :(得分:1)

答案中尚未注明的另一个技术差异:如果您将自己限制在xsl:element构造函数中,则样式表可以对XSLT的DTD有效。在某些环境中(例如,您有一个支持DTD的编辑器),这可能是有利的。也就是说,我多次被告知没有人真正使用DTD来指导他们的XSLT构建(除了我,就是这样)。

还存在形而上学的差异(文字结果元素可以被视为标记滥用的一种形式,因为你使用的是h1,其含义是而不是“这是一个第一级标题“但是”将第一级标题放在这里“),但这主要是为了标记理论家和语言设计者;我只是为了完整性而提到它。

答案 3 :(得分:1)

我强烈建议在可能的地方使用文字结果元素

因此,如果事先知道元素的名称(未动态确定)并且不需要命名空间操作,则使用文字结果元素。

xsl:element相比,使用文字结果元素的主要优点是可读性和移动部件少 - 这意味着更不容易出错