将 XML 转换为文本(csv 文件)按属性排序
transforming XML to text (csv file) sorting by attribute
我是 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> </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
如果没有看到预期的输出,很难准确地说出你想要什么。既然你说“line="9" 的输出应该是第二行,我猜你想这样做(而且只有这个):
<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> </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> </xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
(*) 假设所有 CSVIMP
元素都具有这两个属性。
我是 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> </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
如果没有看到预期的输出,很难准确地说出你想要什么。既然你说“line="9" 的输出应该是第二行,我猜你想这样做(而且只有这个):
<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> </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> </xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
(*) 假设所有 CSVIMP
元素都具有这两个属性。