使用xsl:value-of作为xsl:element的名称

7

我将要处理一个包含列表结构的XML文件:

<list>
  <listItem>
    <name>elementOne</name>
    <value>elementOneValue</name>
  </listItem>
  <listItem>
    <name>elementTwo</name>
    <value>elementTwoValue</name>
  </listItem>
</list>

我正在尝试将其转换为以下结构:

<elementOne>elementOneValue</elementOne>
<elementTwo>elementTwoValue</elementTwo>

这是一种易于使用XSL实现的逻辑,但我遇到了一些复杂情况。
<xsl:for-each select="/list/listItem">
  <xsl:element name="<xsl:value-of select="name"/>">
    <xsl:value-of select="value"/>
  </xsl:element>
</xsl:for-each>

由于我认为连续的双引号破坏了 <xsl: element> 标签,所以无法工作。
<xsl:for-each select="/list/listItem">
  <<xsl:value-of select="name"/>>
    <xsl:value-of select="value"/>
  </<xsl:value-of select="name"/>>
</xsl:for-each>

无法正常工作,因为我无法使用<<>>

<xsl:for-each select="/list/listItem">
  &lt;<xsl:value-of select="name"/>&gt;
    <xsl:value-of select="value"/>
  &lt;/<xsl:value-of select="name"/>&gt;
</xsl:for-each>

这段代码无法正常工作,因为它包含了 > 和 < 这样的字符,而不是可被 XML 解析的 <>。我原以为这是一个很简单的问题,但在互联网上找不到任何相关记录。请问有什么简单的解决方法吗?


好问题,+1。请查看我的答案,使用xsl:element提供了完整而简短的解决方案。 :) - Dimitre Novatchev
3个回答

14

这里有一种完整且简短的解决方案,使用<xsl:element> XSLT指令:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="listItem">
   <xsl:element name="{name}">
     <xsl:value-of select="value"/>
   </xsl:element>
 </xsl:template>
</xsl:stylesheet>

当对提供的XML文档(已更正为格式正确)应用此转换时:

<list>
    <listItem>
        <name>elementOne</name>
        <value>elementOneValue</value>
    </listItem>
    <listItem>
        <name>elementTwo</name>
        <value>elementTwoValue</value>
    </listItem>
</list>

所需的结果已经产生:

<elementOne>elementOneValue</elementOne>
<elementTwo>elementTwoValue</elementTwo>

请注意

  1. 使用 <xsl:element> 指令 来创建一个名称静态未知的元素。

  2. 使用 AVT (Attribute-Value-Template) 以更紧凑和易读的方式指定 name 属性。

  3. 如果元素一 (elementOne) 和 元素二 (elementTwo) 的字符串值不遵守元素名 (QName) 的词法/语法规则,则可能会引发错误。


7
我相信你可以使用花括号代替<xsl:value-of>标签:
<xsl:element name="{name}">
    <xsl:value-of select="value"/>
</xsl:element>

我本来在找别的东西,但这就是我要找的答案...谢谢! - confiq

0

没有试过,但这应该可以工作...

   <xsl:for-each select="/list/listItem">
      <xsl:variable name="elemName" select="name"/>
      <xsl:element name="$elemName">
        <xsl:value-of select="value"/>
      </xsl:element>
    </xsl:for-each>

接近了,但你需要转义变量<xsl:element name="{$elemName}">。 - AntonK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接