6

我最近才开始使用 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>

这两者之间的实际区别是什么?如果存在差异,它们中的哪一个被认为是“好风格”

4

4 回答 4

8

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

<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>是计算元素名称而不是“编译时”文字。

于 2012-09-24T16:30:05.040 回答
4

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

于 2012-09-24T16:29:54.367 回答
1

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

还有一个形而上学的区别(字面结果元素可以被视为标签滥用的一种形式,因为您使用h1的意思不是“这是一级标题”而是“在此处放置一级标题” "),但这主要是标记理论家和语言设计者感兴趣的;我只是为了完整起见才提到它。

于 2012-09-24T16:58:20.060 回答
1

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

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

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

于 2012-09-25T02:48:05.197 回答