是否有 XSLT 元素名称?

Posted

技术标签:

【中文标题】是否有 XSLT 元素名称?【英文标题】:Is there an XSLT name-of element? 【发布时间】:2010-10-09 18:33:59 【问题描述】:

在 XSLT 中有

<xsl:value-of select="expression"/>

获取元素的值,但是有什么东西可以选择元素的标签名吗?

在这样的情况下:

<person>
  <!-- required stuff -->
  <name>Robert</name>
  <!-- optional stuff, free form for future extension. 
       Using XMLSchema's xsd:any -->
  <profession>programmer</profession>
  <hobby>photography</hobby>
</person>

<xsl:for-each select="person">
   <xsl:tag-of select="."/> : <xsl:value-of select="."/>
</xsl:for-each>

要得到这样的输出:

name : Robert
profession : programmer
hobby : photography

当然,上面的 XSLT 不会编译,因为

 <xsl:tag-of select="expression"/>

不存在。但是这怎么可能呢?

【问题讨论】:

这个问题最相关的标签是 XPath。这两个函数都是 XPath 标准函数,可以在任何宿主语言(C#、XSLT、XQuery 等)上下文中的 XPath 表达式中使用,请重新标记 此文本:“在 XSLT 中存在 ”——包含错误。 XSLT 指令通常使用的前缀是“xsl”。通常在使用 XML Schema 时,我们使用前缀“xsd”或“xs”。请正确。 【参考方案1】:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
    <xsl:template match="person">
        <xsl:for-each select="*">
            <xsl:text>
       </xsl:text>
            <xsl:value-of select="local-name()"/> : <xsl:value-of select="."/>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

【讨论】:

【参考方案2】:

有兴趣的,没有:

<xsl:tag-of select="."/>

但是您可以通过以下方式重新创建标签/元素:

<xsl:element name="local-name()">
  <xsl:value-of select="substring(.,1,3)"/>
</xsl:element>

这在 xslt 模板中很有用,例如处理许多不同元素的格式化数据值。当您不知道正在处理的元素的名称时,您仍然可以输出相同的元素,并根据需要修改值。

【讨论】:

【参考方案3】:
<xsl:value-of select="name(.)" /> : <xsl:value-of select="."/>

【讨论】:

那么为什么会被否决?如果您也不想要命名空间,Granted 本来可以提到 local-name(),但更广泛的社区解释为什么这不起作用会很有用。 也许它无法转换给定的 XML。在这种情况下,名称(。)将是“人”。应该是“姓名”、“职业”和“爱好”。 @CodeMelt 为什么你没有对接受的答案投反对票?它很好,但比这个更具体。我对 Rowland Shaw 的回答投了赞成票,因为它提供了问题的答案。请仅在回答包含错误、不正确或误导性信息时投反对票 修复了那个小细节 - 就个人而言,我认为人们应该解释为什么某事被否决,因为它有助于解释集体知识...... 我们的声誉可能会引起注意,但由于它们并不能保证我们发布的内容是值得的,因此真正重要的是我们贡献的质量。没有任何理由会导致低质量的贡献。【参考方案4】:
<xsl:for-each select="person">
  <xsl:for-each select="*">
    <xsl:value-of select="local-name()"/> : <xsl:value-of select="."/>
  </xsl:for-each>  
</xsl:for-each>

【讨论】:

作为一个好习惯,在获取节点的值时始终使用 normalize-space() 这将修剪多余的空格 只有在输入收集阶段没有进行处理时才需要这种规范化/清理。然后这样做可以节省在访问时必须这样做,这通常要频繁得多。可以在添加到 RDB 之前执行此操作,而 xml 文档只是另一个数据库。【参考方案5】:

没有人指出函数 name()local-name() 语义的细微差别。

name(someNode) 返回完整的 节点的名称,其中包括 节点的前缀和冒号 是一个元素或一个属性。 local-name(someNode) 只返回 节点的本地名称,以及 不包括前缀和冒号 如果节点是一个元素或一个 属性。

因此,在一个名称可能属于两个不同命名空间的情况下,必须使用name() 函数才能区分这些名称。

而且,顺便说一句,可以在没有任何参数的情况下指定这两个函数

name()name(.)

的缩写

local-name()local-name(.)

的缩写

最后,请记住,不仅元素和属性有名称,这两个函数也可以在 PI 上使用,并且它们是相同的)。

【讨论】:

【参考方案6】:

这将为您提供当前元素名称(标签名称)

<xsl:value-of select ="name(.)"/>

OP-Edit:这也可以解决问题:

<xsl:value-of select ="local-name()"/>

【讨论】:

本地名称是你想要的 10 次中有 9 次 local-name 是无命名空间,这就是为什么它通常更好。

以上是关于是否有 XSLT 元素名称?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 XSLT 将名称空间添加到我的 XML 的根元素?

删除 XSLT 映射生成的元素的名称空间前缀

在 XSLT 中匹配具有名称空间前缀的元素

XML 元素名称中包含的 XSLT 命名空间 URI

使用元素名称将输入 XML 传递给 XSLT 中的变量

如何使用 XSLT 为所有元素和属性添加名称空间和前缀?