使用xslt将xml转换为csv

使用xslt将xml转换为csv,xml,xslt,xpath,Xml,Xslt,Xpath,以下代码将xml更改为csv 当它应用于以下样本数据时 <Addy> <Row> <L>1</L> <LD>Dwelling</LD> <Th>Passage</Th> </Row> </ADDY> 其思想是去掉列名,并在最后一个值的末尾添加逗号(,) 以达到预期的效果 1,Dwelling,passage, 除去 在行模式下的*的模板中。如果每个行的元素顺序相同,则不需

以下代码将xml更改为csv

当它应用于以下样本数据时

 <Addy>
<Row>
<L>1</L>
<LD>Dwelling</LD>
<Th>Passage</Th>
</Row>
</ADDY>
其思想是去掉列名,并在最后一个值的末尾添加逗号(,) 以达到预期的效果

1,Dwelling,passage,
除去


行模式下的
*
模板中。

如果每个
行的元素顺序相同
,则不需要任何复杂的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>

只需修改模板匹配
/
,现在应该是:

   <xsl:template match="/">
    <xsl:apply-templates select="*/*" mode="row"/>
   </xsl:template>
<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>
生成所需的正确结果

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

你能保证没有值会有逗号吗?如果可能的话,你想要什么样的输出?@lee,输出行已经编号了——你是说别的吗?@lee,哦,我明白了。下班后我可以看一看这个——大约9小时后。@lee,我确实读过这个问题,但很难理解你想要什么…@DImitre,你能添加关于上述代码的详细信息以更好地理解和记录吗?谢谢。@lee,这很简单——我对您的原始代码只做了两件事:1。删除了对“not last”的检查,这样即使在最后一行组件之后也会添加逗号。2.增加了一个

--在输出每行的CSV表示后生成换行符。
1,Dwelling,Passage,
2,Foo,Bar,
   <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>
<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,