将元素列表转换为逗号分隔序列

时间:2010-11-11 11:51:27

标签: xml xslt

我想要的是一个XSLT模板,用于将多个XML元素值转换为逗号分隔的字符串,使其成为单个输出元素的值。

我在教程中找到了几个用于 text 输出的示例,但没有用于XML输出。

示例输入:

<People>
    <Person>John</Person>
    <Person>Paul</Person>
    <Person>George</Person>
    <Person>Ringo</Person>
</People>

期望的输出:

<Output>
    <People>John,Paul,George,Ringo</People>
</Output>

这是我到目前为止所得到的:

<?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

    <xsl:template match="/">
         <xsl:element name="Output">
                <xsl:element name="People">
                       <xsl:for-each select="People/Person">
                              <xsl:value-of select="."/>
                              <xsl:text>,</xsl:text>
                       </xsl:for-each>
                </xsl:element>
         </xsl:element>
    </xsl:template>

</xsl:stylesheet>

但我不知道如何使用这种方法摆脱最后一次昏迷。有什么想法吗?

2 个答案:

答案 0 :(得分:3)

此转化

<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="/*">
  <People>
    <xsl:apply-templates/>
  </People>
 </xsl:template>

 <xsl:template match="Person">
  <xsl:value-of select=
    "concat(.,
            substring(',', 1 div not(position()=last()))
            )"/>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档

<People>
    <Person>John</Person>
    <Person>Paul</Person>
    <Person>George</Person>
    <Person>Ringo</Person>
</People>

产生想要的结果

<People>John,Paul,George,Ringo</People>

请注意

  1. 序列中的项目之间没有假设结构依赖 - 例如我们不使用它们是兄弟姐妹的事实。

  2. 上述事实使我们的转换更通用 - 它可以用于序列中的项不是兄弟,甚至属于多个XML文档的情况。

  3. 聪明的XPath 1.0技巧有助于避免为第一个/最后一个项目和其他项目设置不同的模板

  4. 在XPath 1.0 true()中,false()转换为10

    1 div 0positive-infinitysubstring(anyString, 1, $x) $xpositive-infinity,是完整的字符串。

答案 1 :(得分:2)

这应该有效:

<?xml version="1.0" encoding="ISO-8859-1"?>

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

<xsl:template match="/">
<Output>
 <People>
   <xsl:apply-templates select="People/Person" />
 </People>
</Output>
</xsl:template>

<xsl:template match="Person">
  <xsl:value-of select="normalize-space(.)" /><xsl:if test="following-sibling::Person">,</xsl:if>
</xsl:template>

</xsl:stylesheet>

注意:这不会产生带有每个值的引号的CSV。