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

Pri*_*mre 4 xml xslt

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

我可以<xsl:element>顺便说一下:

<xsl:element name="h1">
    <xsl:value-of select="heading"/>
</xsl:element>
Run Code Online (Sandbox Code Playgroud)

2.或者手动定义元素:

<h1>
    <xsl:value-of select="heading"/>
</h1>
Run Code Online (Sandbox Code Playgroud)

这两者之间的实际差异是什么,如果存在差异,哪些被认为是"好风格"

Ian*_*rts 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>
Run Code Online (Sandbox Code Playgroud)

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

<?xml version="1.0"?>
<root xmlns:foo="http://example.com">
  <foo:element1/>
  <foo:element2/>
</root>
Run Code Online (Sandbox Code Playgroud)

但改变<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>
Run Code Online (Sandbox Code Playgroud)

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

<xsl:copy-of select="document('')/*/namespace::foo" />
Run Code Online (Sandbox Code Playgroud)

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

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


Paw*_*wel 5

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