将XML转换为按属性排序的文本(csv文件)

时间:2016-12-03 18:47:02

标签: xml sorting csv xslt saxon

我是XSLT 2.0的新手,我必须将XML转换为文本文件(CSV),但我希望输出符合行属性顺序(请参阅下面的XML,样式表和输出) 。正如你可以看到line =" 9"的输出应该是第二行。问题是如何更改样式表以实现正确的输出?

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <MP>        
        <CSVIMP line="10" content="xyz"/>
        <CSVIMP line="11" content="123"/>
        <CSVIMP line="8" content="123"/>
    </MP>
    <MP>
        <CSVIMP line="9" content="abc"/>
        <CSVIMP line="12" content="456"/>
    </MP>
</root>

我的样式表:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="text" encoding="UTF-8" />

    <xsl:variable name="delimiter" select="','"/>

    <xsl:template match="MP">
        <xsl:for-each select="CSVIMP">
            <xsl:sort select="./@line" data-type="number"></xsl:sort>
            <xsl:value-of select="./@line"/>
            <xsl:value-of select="$delimiter"/>
            <xsl:value-of select="./@content"/>
            <xsl:text>&#10;</xsl:text>
        </xsl:for-each>
    </xsl:template>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="text()"></xsl:template>
</xsl:transform>

转换输出(Saxon 9.5 HE):

8,123
10,xyz
11,123
9,abc
12,456

1 个答案:

答案 0 :(得分:1)

如果没有看到预期的输出,很难确切地说出你想要的东西。因为你说&#34; line =&#34; 9&#34;的输出应该是第二行,我想你想这样做(只有这个):

<xsl:template match="/root">
    <xsl:for-each select="MP/CSVIMP">
        <xsl:sort select="./@line" data-type="number"></xsl:sort>
        <xsl:value-of select="./@line"/>
        <xsl:value-of select="$delimiter"/>
        <xsl:value-of select="./@content"/>
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
</xsl:template>

既然您正在使用XSLT 2.0,那么您可能会将整个事情缩短为:

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8" />

<xsl:template match="/root">
    <xsl:for-each select="MP/CSVIMP">
        <xsl:sort select="./@line" data-type="number"/>
        <xsl:value-of select="@line, @content" separator=","/>
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

(*)假设所有CSVIMP元素都具有两个属性。