我循环遍历一组节点,每个节点都有两个元素,并希望为每个组输出一个两列表。该表按字母顺序排序,沿第一列向下排序,然后沿第二列向下排序。我正在对第一个元素进行分组,然后在两列中输出每个第二个元素。
示例数据来源:
<ArrayOfEIS_CT_AssignmentByRegion
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<EIS_CT_AssignmentByRegion>
<Region>MIDDLE EAST, NORTH AFRICA and EUROPE</Region>
<CountryName>IRAQ</CountryName>
</EIS_CT_AssignmentByRegion>
<EIS_CT_AssignmentByRegion>
<Region>MIDDLE EAST, NORTH AFRICA and EUROPE</Region>
<CountryName>JORDAN</CountryName>
</EIS_CT_AssignmentByRegion>
<EIS_CT_AssignmentByRegion>
<Region>MIDDLE EAST, NORTH AFRICA and EUROPE</Region>
<CountryName>GAZA AND WEST BANK</CountryName>
</EIS_CT_AssignmentByRegion>
<EIS_CT_AssignmentByRegion>
<Region>MIDDLE EAST, NORTH AFRICA and EUROPE</Region>
<CountryName>KUWAIT</CountryName>
</EIS_CT_AssignmentByRegion>
<EIS_CT_AssignmentByRegion>
<Region>SUBSAHARAN AFRICA</Region>
<CountryName>TOGO</CountryName>
</EIS_CT_AssignmentByRegion>
<EIS_CT_AssignmentByRegion>
<Region>SUBSAHARAN AFRICA</Region>
<CountryName>ZIMBABWE</CountryName>
</EIS_CT_AssignmentByRegion>
<EIS_CT_AssignmentByRegion>
<Region>SUBSAHARAN AFRICA</Region>
<CountryName>ZAMBIA</CountryName>
</EIS_CT_AssignmentByRegion>
<EIS_CT_AssignmentByRegion>
<Region>SUBSAHARAN AFRICA</Region>
<CountryName>UGANDA</CountryName>
</EIS_CT_AssignmentByRegion>
</ArrayOfEIS_CT_AssignmentByRegion>
XSLT:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:w="http://schemas.microsoft.com/office/word/2006/wordml">
<xsl:output method="xml" indent="yes" encoding="utf-8"/>
<xsl:key name="list-by-region" match="EIS_CT_AssignmentByRegion" use="concat(generate-id(..), '|', Region)"/>
<xsl:template match="/ArrayOfEIS_CT_AssignmentByRegion">
<html>
<body>
<xsl:for-each select="EIS_CT_AssignmentByRegion[generate-id() = generate-id(key('list-by-region', concat(generate-id(..), '|', Region))[1])]">
<xsl:sort select="Region" />
<xsl:sort select="CountryName" />
<xsl:variable name="halfIndex" select="floor(count(key('list-by-region', concat(generate-id(..), '|', Region))) div 2)" />
<table>
<thead>
<tr>
<th colspan="2">
<xsl:value-of select="Region" />
</th>
</tr>
</thead>
<tbody>
<xsl:for-each select="key('list-by-region', concat(generate-id(..), '|', Region))">
<xsl:sort select="CountryName" />
<xsl:variable name="countryColumn2" select="following-sibling::*[position() = $halfIndex]" />
<xsl:if test="position() <= $halfIndex">
<tr>
<td>
<xsl:value-of select="CountryName" />
</td>
<td>
<xsl:value-of select="$countryColumn2" />
</td>
</tr>
</xsl:if>
</xsl:for-each>
</tbody>
</table>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
我想要的输出是:
<html>
<body>
<table>
<thead>
<tr>
<th colspan="2">
MIDDLE EAST, NORTH AFRICA and EUROPE
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
GAZA AND WEST BANK
</td>
<td>
JORDAN
</td>
</tr>
<tr>
<td>
IRAQ
</td>
<td>
KUWAIT
</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th colspan="2">
SUBSAHARAN AFRICA
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
TOGO
</td>
<td>
ZAMBIA
</td>
</tr>
<tr>
<td>
UGANDA
</td>
<td>
ZIMBABWE
</td>
</tr>
</tbody>
</table>
</body>
</html>
我的方法是只处理每组的一半,并从后半部分选择国家,然后在第二列输出。我的问题是,对于某些组,正在选择错误的国家/地区。通常,选择来自另一组的国家。
为了进行测试,我按顺序输出了所有国家/地区,单列,并且正在对它们进行分组和正确排序。所以这一行
<xsl:variable name="countryColumn2"
select="following-sibling::*[position() = $halfIndex]" />
对于某些组,保留当前上下文以选择兄弟节点。有任何想法吗?感谢。
答案 0 :(得分:1)
<xsl:variable name="countryColumn2" select="following-sibling::*[position() = $halfIndex]" />
对于某些组,请保留当前上下文以选择兄弟 节点。有什么想法吗?
好问题,+ 1。
使用<xsl:sort>
排序不会更改XML文档中节点之间的原始兄弟关系。
因此,对于两个节点:node1
及其后续的兄弟node2,
虽然node1
作为排序结果出现在node2
之后,但仍然是{{1} }}是node2
的后续兄弟。
解决方案:
Pass1 :在临时树中输出排序结果,在此树中,节点之间的兄弟关系正好反映了它们的排序顺序。
Pass2 :在第一遍传递结果的第二遍中继续处理。现在您可以按预期的方式使用兄弟轴。