在 XML 到 XML 转换中使用 XSLT v1.0 连接
Concatenate using XSLT v1.0 in XML to XML transformation
我正在做一个 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 节点中出现一次。
您可以使用此 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>
...
但请注意,此范围将忽略间隙并仅使用最低值和最高值。
我正在做一个 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 节点中出现一次。
您可以使用此 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>
...
但请注意,此范围将忽略间隙并仅使用最低值和最高值。