XML到CSV的问题

时间:2010-06-04 08:12:03

标签: xml xslt

我正在尝试将xml转换为csv。我面临的问题是将子节点(如ProdIDT,IDV)作为一行选项卡删除txt文件。子节点值接近没有标题。请查看下面的输入和XSL文件。

XML

<Product>
<Record>1616200243</Record>
<Not>03</Not>
<ProductId>
<ProdIDT>02</ProdIDT>
<IDV>1616200243</IDV>
</ProductId>
<ProductId>
<ProdIDT>03</ProdIDT>
<IDV>9781616200244</IDV>
</ProductId>
<ProdFormDe>Electronic book text</ProdFormDe>
<EpTy>000</EpTy>
<NoS/>
<Title>
<TitleT>01</TitleT>
<TTx>The Sound of a Wild Snail Eating</TTx>
<Sbt>A Memoir</Sbt>
</Title>
</Product>

我的XSL

  

<xsl:for-each select="//Product/child::*|//Product/self::*">

  <xsl:if test="$fieldNames = 'yes'">

    <xsl:if test="position() = 1 or position()&gt;1">

      <xsl:for-each select="@*">
        <xsl:value-of select="name()"/>

        <xsl:value-of select="$delimiter"/>

      </xsl:for-each>

      <xsl:for-each select="*">
        <xsl:value-of select="name()"/>

        <xsl:if test="position() != last()">
          <xsl:value-of select="$delimiter"/>
        </xsl:if>
      </xsl:for-each>
      <xsl:text>
    </xsl:text>
    </xsl:if>
  </xsl:if>
  <xsl:for-each select="@*">
    <xsl:value-of select="."/>
    <xsl:value-of select="$delimiter"/>
  </xsl:for-each>
  <xsl:for-each select="*">
    <xsl:value-of select="."/>
    <xsl:if test="position() != last()">
      <xsl:value-of select="$delimiter"/>
    </xsl:if>
  </xsl:for-each>
  <xsl:text>

       

必需输出

Record          Not     ProductId   ProdIDT IDV             ProductId       ProdIDT IDV             ProdFormDe      EpTy    NoS Title           TitleT  TTx     Sbt
1616200243      03                      02      1616200243                      03      9781616200244   Electronic book text            000             01      The Sound of a Wild Snail Eating        A Memoir

由于 Byomokesh

3 个答案:

答案 0 :(得分:0)

像这样

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

<xsl:template match="/">
  <xsl:for-each select="/*//*">
   <xsl:value-of select="concat(name(), '&#9;')"/>
  </xsl:for-each>
  <xsl:text>&#xA;</xsl:text>
  <xsl:for-each select="/*//*">
    <xsl:value-of select="concat(text(), '&#9;')"/>
  </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

答案 1 :(得分:0)

基本上,你需要2个循环。一个for-each产品,在该循环内部,应该有另一个产品的所有属性。在每个产品之后,写出换行符。 像这样:

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

  <xsl:template match="/">
    <xsl:for-each select="//Product[position()=1]">
      <xsl:for-each select=".//*">
        <xsl:value-of select="name()" />
        <xsl:call-template name="WriteTab" />
      </xsl:for-each>
    </xsl:for-each>
    <xsl:call-template name="WriteNewLine" />

    <xsl:for-each select="//Product">
      <xsl:for-each select=".//*">
        <xsl:value-of select="text()" />
        <xsl:call-template name="WriteTab" />
      </xsl:for-each>
      <xsl:call-template name="WriteNewLine" />
    </xsl:for-each>
  </xsl:template>

  <xsl:template name ="WriteNewLine">
    <xsl:text>
</xsl:text>
  </xsl:template>

  <xsl:template name="WriteTab">
    <xsl:text>&#9;</xsl:text>
  </xsl:template>

答案 2 :(得分:0)

此样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:template match="/*">
        <xsl:apply-templates select="*[1]" mode="header"/>
        <xsl:apply-templates/>
    </xsl:template>
    <xsl:template match="*[not(*)]" mode="header">
        <xsl:value-of
         select="concat(name(),
                        substring('&#x9;&#xA;',
                                  1+boolean(following::*[1][self::Product]
                                            or not(following::*[1])),
                                  1))"/>
    </xsl:template>
    <xsl:template match="*[not(*)]">
        <xsl:value-of
         select="concat(.,
                        substring('&#x9;&#xA;',
                                  1+boolean(following::*[1][self::Product]
                                            or not(following::*[1])),
                                  1))"/>
    </xsl:template>
</xsl:stylesheet>

使用此输入:

<root>
    <Product>
        <Record>1616200243</Record>
        <Not>03</Not>
        <ProductId>
            <ProdIDT>02</ProdIDT>
            <IDV>1616200243</IDV>
        </ProductId>
        <ProductId>
            <ProdIDT>03</ProdIDT>
            <IDV>9781616200244</IDV>
        </ProductId>
        <ProdFormDe>Electronic book text</ProdFormDe>
        <EpTy>000</EpTy>
        <NoS/>
        <Title>
            <TitleT>01</TitleT>
            <TTx>The Sound of a Wild Snail Eating</TTx>
            <Sbt>A Memoir</Sbt>
        </Title>
    </Product>
</root>

输出:

Record  Not ProdIDT IDV ProdIDT IDV ProdFormDe  EpTy    NoS TitleT  TTx Sbt
1616200243  03  02  1616200243  03  9781616200244   Electronic book text    000     01  The Sound of a Wild Snail Eating    A Memoir