Проблема XML в CSV - PullRequest
       16

Проблема XML в CSV

0 голосов
/ 04 июня 2010

Я пытаюсь конвертировать XML в CSV. Я сталкиваюсь с проблемой, чтобы получить дочерний узел (например, ProdIDT, IDV) как одну строку в текстовом файле с разделителями табуляции Значение дочернего узла приближается без заголовка. Пожалуйста, посмотрите ниже мой входной файл и 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 голосов
/ 01 сентября 2010

в принципе, вам нужно 2 цикла. Один продукт для каждого продукта, и внутри этого цикла должен быть другой для всех свойств продукта. И после каждого продукта выписывайте символ новой строки. Примерно так:

<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>

0 голосов
/ 01 сентября 2010

Эта таблица стилей:

<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
0 голосов
/ 04 июня 2010

как-то так :

<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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...