我的XML看起来像这样:
<ROW ref="0005631" type="04" line="1" value="Australia"/>
<ROW ref="0005631" type="00" line="1" value="John"/>
<ROW ref="0005631" type="02" line="1" value="Builder"/>
<ROW ref="0005631" type="01" line="1" value="Smith"/>
我需要一个XSL解决方案来格式化它,看看这个:
John Smith Builder Australia
任何帮助都会很棒。我有很多不同的数据,许多不同的类型和行都是混合的,所以我不想硬编码。
答案 0 :(得分:2)
要对数据使用xsl:sort
,您需要拥有一个父节点,该节点在示例代码中没有提供,但必须有一个以使XML文档有效。假设父节点为<TABLE />
,您的输入将是。
<TABLE>
<ROW ref="0005631" type="04" line="1" value="Australia"/>
<ROW ref="0005631" type="00" line="1" value="John"/>
<ROW ref="0005631" type="02" line="1" value="Builder"/>
<ROW ref="0005631" type="01" line="1" value="Smith"/>
</TABLE>
然后,您可以使用以下XSLT来实现所需的结果,假设您仅根据类型列的值进行排序。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="TABLE">
<xsl:apply-templates>
<xsl:sort select="@type" data-type="number"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="ROW">
<xsl:apply-templates select="@value"/>
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>
如果您想基于ref进行排序,请键入,而不是简单地键入,您可以使用以下TABLE
模板。
<xsl:template match="TABLE">
<xsl:apply-templates>
<xsl:sort select="@ref" data-type="number"/>
<xsl:sort select="@type" data-type="number"/>
<xsl:sort select="@line" data-type="number"/>
</xsl:apply-templates>
</xsl:template>
我无法准确确定您的问题所需的排序顺序,但鉴于这两个例子,任何替代方案都应该是直截了当的。
答案 1 :(得分:0)
您的意思是,您想从同一行获取元素,然后根据类型编号显示它?我认为xsl:sort
是您需要的
答案 2 :(得分:0)
在XSLT 1.0中:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:output method="text" encoding="utf-8" />
<!-- index ROWs by their @ref -->
<xsl:key name="kRowByRef" match="ROW" use="@ref" />
<!-- index ROWs by their @ref and @line -->
<xsl:key name="kRowByRefAndLine" match="ROW" use="concat(@ref, ',', @line)" />
<xsl:template match="/*">
<!-- 1) rows are processed with "ORDER BY @ref" -->
<xsl:apply-templates select="ROW" mode="ref-group">
<xsl:sort select="@ref" data-type="number" />
</xsl:apply-templates>
</xsl:template>
<xsl:template match="ROW" mode="ref-group">
<!-- 2) rows are grouped by @ref -->
<xsl:variable name="thisGroup" select="
key('kRowByRef', @ref)
" />
<xsl:if test="generate-id() = generate-id($thisGroup[1])">
<!-- 2.1) for the first item in the group,
nodes are processed with "ORDER BY @line" -->
<xsl:apply-templates select="$thisGroup" mode="line-group">
<xsl:sort select="@line" data-type="number" />
</xsl:apply-templates>
<!-- use a line as record separator -->
<xsl:text>---------------------------- </xsl:text>
</xsl:if>
</xsl:template>
<xsl:template match="ROW" mode="line-group">
<!-- 3) rows are grouped by @ref, @line -->
<xsl:variable name="thisGroup" select="
key('kRowByRefAndLine', concat(@ref, ',', @line))
" />
<xsl:if test="generate-id() = generate-id($thisGroup[1])">
<!-- 3.1) for the first item in the group,
nodes are processed with "ORDER BY @type" -->
<xsl:apply-templates select="$thisGroup" mode="line">
<xsl:sort select="@type" data-type="number" />
</xsl:apply-templates>
</xsl:if>
</xsl:template>
<xsl:template match="ROW" mode="line">
<!-- 4) rows are printed out & appended with space or newline -->
<xsl:value-of select="@value" />
<xsl:choose>
<xsl:when test="position() = last()">
<xsl:text> </xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text> </xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
对于这个完全无序的输入:
<data>
<ROW ref="0005631" type="04" line="1" value="Australia"/>
<ROW ref="0005632" type="00" line="1" value="Jack"/>
<ROW ref="0005631" type="00" line="1" value="John"/>
<ROW ref="0005631" type="01" line="1" value="Smith"/>
<ROW ref="0005632" type="04" line="2" value="Whiskey"/>
<ROW ref="0005632" type="02" line="1" value="Tennessee"/>
<ROW ref="0005631" type="02" line="1" value="Builder"/>
<ROW ref="0005632" type="01" line="1" value="Daniel's"/>
</data>
我明白了:
John Smith Builder Australia ---------------------------- Jack Daniel's Tennessee Whiskey ----------------------------
<强>解释强>
此处发生的是分阶段分组和排序,以便最终结果按@ref
,@line
和@type
进行分组和排序。
所有分组都是Muenchian分组。模板#1以<ROW>
顺序处理所有@ref
元素:
<ROW ref="0005631" type="04" line="1" value="Australia"/>
<ROW ref="0005631" type="00" line="1" value="John"/>
<ROW ref="0005631" type="01" line="1" value="Smith"/>
<ROW ref="0005631" type="02" line="1" value="Builder"/>
<ROW ref="0005632" type="00" line="1" value="Jack"/>
<ROW ref="0005632" type="04" line="2" value="Whiskey"/>
<ROW ref="0005632" type="02" line="1" value="Tennessee"/>
<ROW ref="0005632" type="01" line="1" value="Daniel's"/>
模板#2仅处理每个@ref
组中的第一个:
<ROW ref="0005631" type="04" line="1" value="Australia"/>
<ROW ref="0005632" type="00" line="1" value="Jack"/>
以$thisGroup
顺序分两步将整个论坛(@line
)交给模板#3:
<ROW ref="0005631" type="04" line="1" value="Australia"/>
<ROW ref="0005631" type="00" line="1" value="John"/>
<ROW ref="0005631" type="01" line="1" value="Smith"/>
<ROW ref="0005631" type="02" line="1" value="Builder"/>
<ROW ref="0005632" type="00" line="1" value="Jack"/>
<ROW ref="0005632" type="02" line="1" value="Tennessee"/>
<ROW ref="0005632" type="01" line="1" value="Daniel's"/>
<ROW ref="0005632" type="04" line="2" value="Whiskey"/>
模板#3占据每个@line
组的第一个:
<ROW ref="0005631" type="04" line="1" value="Australia"/>
<ROW ref="0005632" type="00" line="1" value="Jack"/>
<ROW ref="0005632" type="04" line="2" value="Whiskey"/>
并处理它们,按@type
顺序分三个步骤将整个组交给模板#4:
<ROW ref="0005631" type="00" line="1" value="John"/>
<ROW ref="0005631" type="01" line="1" value="Smith"/>
<ROW ref="0005631" type="02" line="1" value="Builder"/>
<ROW ref="0005631" type="04" line="1" value="Australia"/>
<ROW ref="0005632" type="00" line="1" value="Jack"/>
<ROW ref="0005632" type="01" line="1" value="Daniel's"/>
<ROW ref="0005632" type="02" line="1" value="Tennessee"/>
<ROW ref="0005632" type="04" line="2" value="Whiskey"/>
模板#4将它们打印出来,在适当的位置附加空格或换行符。