我正在做一个XSLT样式表,以从XML转换为XML,布局非常不同,我的情况令人头疼。我只能使用XSLT 1.0,但找不到解决方法。
输入文件
<?xml version="1.0"?>
<Root>
<ParentNode>
<Node>
<Id>1</Id>
<Date>2019-02-01</Date>
<ReferenceLine>1</ReferenceLine>
</Node>
<Node>
<Id>2</Id>
<Date>2019-02-01</Date>
<ReferenceLine>1</ReferenceLine>
</Node>
<Node>
<Id>3</Id>
<Date>2019-02-02</Date>
<ReferenceLine>2</ReferenceLine>
</Node>
</ParentNode>
</Root>
输出文件
<Lines>
<Line>
<LineNum>1</LineNum>
<Node>1 - 2</Node>
</Line>
<Line>
<LineNum>2</LineNum>
<Node>3</Node>
</Line>
</Lines>
因此,我需要在输出中连接参照该行出现的所有节点。虽然在输入文件中可以出现Node的多个事件,但在输出文件中,在Line节点中只能出现一个的事件。
答案 0 :(得分:1)
您可以使用 XSLT-1.0 方法Muenchian Grouping来实现。如果您搜索SO,则会发现很多示例。应用此方法,您的样式表应如下所示。
此样式表将由Id
分隔的所有-
连接起来。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:key name="nd" match="Node" use="ReferenceLine" />
<xsl:template match="/Root/ParentNode">
<Lines>
<xsl:for-each select="Node[generate-id() = generate-id(key('nd',ReferenceLine)[1])]">
<Line>
<LineNum><xsl:value-of select="Id" /></LineNum>
<Node>
<xsl:for-each select="key('nd',ReferenceLine)">
<xsl:sort order="ascending" select="Id" />
<xsl:value-of select="Id" />
<xsl:if test="position() != last()">
<xsl:text> - </xsl:text>
</xsl:if>
</xsl:for-each>
</Node>
</Line>
</xsl:for-each>
</Lines>
</xsl:template>
</xsl:stylesheet>
如果只想获取范围,请用以下内容替换内部的for-each
:
...
<xsl:for-each select="key('nd',ReferenceLine)">
<xsl:sort order="ascending" select="Id" />
<xsl:if test="position() = 1">
<xsl:value-of select="Id" />
</xsl:if>
<xsl:if test="position() = last() and position() != 1">
<xsl:value-of select="concat(' - ',Id)" />
</xsl:if>
</xsl:for-each>
...
但是请注意,该范围将忽略差距,仅使用最低和最高值。