【问题标题】:XSLT to convert the nested elements with comma separatedXSLT 转换用逗号分隔的嵌套元素
【发布时间】:2013-05-13 14:30:13
【问题描述】:

我正在尝试将任何 xml 文件转换为 CSV 格式。当 xml 嵌套/子元素时,这些值不会以逗号分隔的形式输出。我在其他帖子中尝试了很多例子,但没有一个能按需要解决。我是 XSLT 的初学者,对此有任何帮助。

    <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
   <S:Body>
         <trade>
            <createdBy>1</createdBy>
            <createdOnDate>2</createdOnDate>
            <Payment>
               <indicator>3</indicator>
               <updateBy>4</updateBy>
            </Payment>
            <Parties>
               <partyId>5</partyId>
               <partyRoleTypeCode>6</partyRoleTypeCode>
            </Parties>
            <Product>
               <term>7</term>
               <shortDescription>8</shortDescription>
            </Product>
         </trade>
         <trade>
            <createdBy>10</createdBy>
            <createdOnDate>20</createdOnDate>
            <Payment>
               <indicator>30</indicator>
               <updateBy>40</updateBy>
            </Payment>
            <Parties>
               <partyId>50</partyId>
               <partyRoleTypeCode>60</partyRoleTypeCode>
            </Parties>
            <Product>
               <term>70</term>
               <shortDescription>80</shortDescription>
            </Product>
         </trade>

   </S:Body>
</S:Envelope>

感谢 OkieOth。我已经尝试了修改后的脚本,但它产生的输出为

1,2,3,4,5,6,7,8,  ( i need to get rid of the last comma , looks keep this comma adding every row)
10,20,30,40,50,60,70,80

请帮忙。我需要在每行的最后一个值之后去掉结尾的逗号。注意:逗号仅在最后一行被删除。

<xsl:template match="//S:Body">
    <xsl:apply-templates select="//trade"/>
</xsl:template>

<xsl:template match="trade">
    <xsl:apply-templates/>
    <xsl:text>&#10;</xsl:text>
</xsl:template>

    <xsl:template match="//text()">
        <xsl:copy-of select="." />
        <xsl:choose>
        <xsl:when test="(following::*)">
                            <xsl:value-of select="','"/>
        </xsl:when>
        </xsl:choose>

    </xsl:template>     

【问题讨论】:

    标签: xml xslt csv transform


    【解决方案1】:

    试试这个:

        <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
      <xsl:output method="text" indent="no"/>
      <xsl:strip-space elements="*"/>
    
      <xsl:template match="/">
        <xsl:call-template name="getProduct">
          <xsl:with-param name="Product" select="//S:Body"/>
        </xsl:call-template>
      </xsl:template>
    
      <xsl:template name="getProduct">
        <xsl:param name="Product"/>
        <xsl:for-each select="$Product/*">
          <xsl:variable name="ProductContent">
            <xsl:choose>
              <xsl:when test="*">
                <xsl:call-template name="getChild">
                  <xsl:with-param name="Child" select="self::*"/>
                </xsl:call-template>
              </xsl:when>
              <xsl:otherwise>
                <xsl:if test="@*">
                  <xsl:for-each select="@*">
                    <xsl:value-of select="."/>
                    <xsl:text>,</xsl:text>
                  </xsl:for-each>
                  <xsl:text>,</xsl:text>
                </xsl:if>
                <xsl:value-of select="."/>
                <xsl:text>,</xsl:text>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:variable>
          <xsl:value-of select="substring($ProductContent,0,string-length($ProductContent))"/>
          <xsl:text>
    
          </xsl:text>
        </xsl:for-each>
      </xsl:template>
    
      <xsl:template name="getChild">
        <xsl:param name="Child"/>
        <xsl:for-each select="$Child/node()">
          <xsl:choose>
            <xsl:when test="* and not(@*)">
              <xsl:call-template name="getChild">
                <xsl:with-param name="Child" select="*"/>
              </xsl:call-template>
            </xsl:when>
            <xsl:when test="text()">
              <xsl:value-of select="."/>
              <xsl:text>,</xsl:text>
            </xsl:when>
            <xsl:when test="*">
              <xsl:for-each select="@*">
                <xsl:value-of select="."/>
                <xsl:text>,</xsl:text>
              </xsl:for-each>
              <xsl:call-template name="getChild">
                <xsl:with-param name="Child" select="*"/>
              </xsl:call-template>
            </xsl:when>
            <xsl:when test="not(*) and @*">
              <xsl:for-each select="@*">
                <xsl:value-of select="."/>
                <xsl:text>,</xsl:text>
              </xsl:for-each>
            </xsl:when>
            <xsl:otherwise>
              <xsl:if test="@*">
                <xsl:for-each select="@*">
                  <xsl:value-of select="."/>
                  <xsl:text>,</xsl:text>
                </xsl:for-each>
                <xsl:text>,</xsl:text>
              </xsl:if>
              <xsl:value-of select="."/>
              <xsl:text>,</xsl:text>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:for-each>
        <xsl:if test="$Child/@* and not($Child/node())">
          <xsl:for-each select="$Child/@*">
            <xsl:value-of select="."/>
            <xsl:text>,</xsl:text>
          </xsl:for-each>
        </xsl:if>
      </xsl:template>
    </xsl:stylesheet>
    

    输出:

    1,2,3,4,5,6,7,8
    
      10,20,30,40,50,60,70,80
    

    你也可以在SOAP Response converting to CSV查看我之前的帖子

    【讨论】:

    • 谢谢 Navin,这会导致编译错误 JAXPSAXProcessorInvoker - 'self::*/* and not(self::*/@*)' 中的语法错误。你能帮助脚本打印每行的“交易”值吗?我几乎让它工作了,但真的不知道我应该如何摆脱每个“交易”值的“最后一个值”之后的最后一个逗号。
    • 我已根据您的要求更新了我的回复。请查看并返回。
    猜你喜欢
    • 2014-03-11
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-01
    • 2015-10-25
    相关资源
    最近更新 更多