2012-09-12 29 views
1

以下代码将xml更改为csv。xml转换为带有xslt的csv

当它被施加到下面的示例数据

<Addy> 
<Row> 
<L>1</L> 
<LD>Dwelling</LD> 
<Th>Passage</Th> 
</Row> 
</ADDY> 

它产生csv文件在此formatincludng的列名

L,LD,Th 
1,Dwelling,Passage 

想法是与列名做掉并在最后一个值的末尾添加逗号(,) 以使预期结果为

1,Dwelling,passage, 
+0

你能保证没有值会有逗号吗?如果可能发生,你会如何获得该输出? – Flynn1179

回答

1

template/删除

<xsl:for-each select="*/*/*[generate-id() = generate-id(key('field',name())[1])]"> 
    <xsl:value-of select="name()" /> 
    <xsl:if test="position() != last()">,</xsl:if> 
</xsl:for-each> 
<xsl:text>&#10;</xsl:text> 

并添加逗号:在templaterow模式

<xsl:text>,&#10;</xsl:text> 

*

1

如果这些元素均在同一顺序为每那么你不需要任何复杂的Muenchian分组的,模板模式等的只是一个很简单的样式就足够了:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0"> 
    <xsl:strip-space elements="*"/> 
    <xsl:output method="text"/> 

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

    <xsl:template match="Row/*"> 
    <xsl:value-of select="." /> 
    <xsl:text>,</xsl:text> 
    </xsl:template> 
</xsl:stylesheet> 

运行此在接下来的输入:

<Addy> 
    <Row> 
    <L>1</L> 
    <LD>Dwelling</LD> 
    <Th>Passage</Th> 
    </Row> 
    <Row> 
    <L>2</L> 
    <LD>Foo</LD> 
    <Th>Bar</Th> 
    </Row> 
</Addy> 

产生输出你后,包括在最后一列值后的尾部逗号:

1,Dwelling,Passage, 
2,Foo,Bar, 
+0

不完全 - 这留下每一行结尾的逗号... –

+2

@DimitreNovatchev这就是要求的问题... –

0

只需修改模板所以现在匹配/它应该是:

<xsl:template match="/"> 
    <xsl:apply-templates select="*/*" mode="row"/> 
    </xsl:template> 

如果你真的想在生产的每一行的末尾尾随逗号,然后替换第一次出现:

<xsl:if test="position() != last()">,</xsl:if> 

有:

<xsl:text>&#10;</xsl:text> 

当仅执行这些最小的修改,所提供的代码变为:

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

    <xsl:key name="field" match="/*/*/*" use="name()" /> 
    <xsl:output method="text"/> 

    <xsl:template match="/"> 
    <xsl:apply-templates select="*/*" mode="row"/> 
    </xsl:template> 

    <xsl:template match="*" mode="row"> 
    <xsl:variable name="row" select="*" /> 
    <xsl:for-each select="/*/*/*[generate-id() = generate-id(key('field',name())[1])]"> 
     <xsl:variable name="name" select="name()" /> 
     <xsl:apply-templates select="$row[name()=$name]" mode="data" /> 
     <xsl:text>,</xsl:text> 
    </xsl:for-each> 
    <xsl:text>&#10;</xsl:text> 
    </xsl:template> 

    <xsl:template match="*" mode="data"> 
    <xsl:choose> 
     <xsl:when test="contains(text(),',')"> 
      <xsl:text>&quot;</xsl:text> 
      <xsl:call-template name="doublequotes"> 
       <xsl:with-param name="text" select="text()" /> 
      </xsl:call-template> 
      <xsl:text>&quot;</xsl:text> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="." /> 
     </xsl:otherwise> 
    </xsl:choose> 
    <xsl:if test="position() != last()">,</xsl:if> 
    </xsl:template> 

    <xsl:template name="doublequotes"> 
    <xsl:param name="text" /> 
    <xsl:choose> 
     <xsl:when test="contains($text,'&quot;')"> 
      <xsl:value-of select="concat(substring-before($text,'&quot;'),'&quot;&quot;')" /> 
      <xsl:call-template name="doublequotes"> 
       <xsl:with-param name="text" select="substring-after($text,'&quot;')" /> 
      </xsl:call-template> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="$text" /> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 
</xsl:stylesheet> 

当在下面的XML文档被应用该转化(注意在这两个元件不同的顺序的孩子)

<Addy> 
    <Row> 
    <L>1</L> 
    <LD>Dwelling</LD> 
    <Th>Passage</Th> 
    </Row> 
    <Row> 
    <Th>Bar</Th> 
    <LD>Foo</LD> 
    <L>2</L> 
    </Row> 
</Addy> 

想要的,正确的结果产生

1,Dwelling,Passage, 
2,Foo,Bar, 
+0

@lee,输出行已经编号 - 你的意思是别的吗? –

+0

@lee,哦,我明白了。下班后我可以在大约9小时后看看这个。 –

+0

@lee,我确实看过这个问题,但很难理解你想要什么... –