代码之家  ›  专栏  ›  技术社区  ›  Antonio Pérez

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

  •  1
  • Antonio Pérez  · 技术社区  · 14 年前

    我想得到的是一个XSLT模板,将多个XML元素值转换成一个coma分隔的字符串,作为单个输出元素的值。

    我在教程中找到了几个这样做的例子 文本 输出,但没有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 回复  |  直到 14 年前
        1
  •  2
  •   Oded    14 年前

    这应该有效:

    <?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,每个值周围都有引号。

        2
  •  3
  •   Dimitre Novatchev    14 年前

    这种转变 :

    <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技巧有助于避免使用不同的模板 对于第一个/最后一个项目和其他项目:

    在XPath 1.0中 true() , false() 转换为 1 , 0 .

    1 div 0 positive-infinity substring(anyString, 1, $x) 哪里 $x 正无穷大 ,是完整的字符串。