从 xml 分组调整字母索引以使列相等 [英] Adjust an alphabetical index from xml grouping to make columns equal

查看:19
本文介绍了从 xml 分组调整字母索引以使列相等的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此处是将字母索引创建为 3 列的场景.但是,将它们分成列的方法有一些改进的余地.

Here is a scenario where an alphabetical index is created into 3 columns. But, the approach for dividing them into columns has some scope of improvement.

使用固定创建字母索引XSLT 2.0 中的列数

在上面的场景中,有没有办法在不破坏字母组的情况下使 3 列尽可能相等.

In the above scenario, is there a way if the 3 columns can be made as much equal as possible without breaking a letter group.

推荐答案

我建议采用以下方法:

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:param name="columns" select="3"/>

<xsl:template match="/countries">
    <xsl:variable name="indexed-countries">
        <xsl:for-each select="country">
            <xsl:sort select="."/>
            <country index="{position()}">
                <xsl:copy-of select="@*|*"/>
            </country>
        </xsl:for-each>
    </xsl:variable>

    <xsl:variable name="groups">
        <xsl:for-each-group select="$indexed-countries/country" group-by="substring(name, 1, 1)">
            <group name="{current-grouping-key()}" cumulative-size="{current-group()[last()]/@index}">
                <xsl:copy-of select="current-group()"/>
            </group>
        </xsl:for-each-group>
    </xsl:variable>

    <xsl:variable name="n" select="count(country)" />
    <xsl:variable name="col-limit" select="ceiling($n div $columns)" />

    <!-- output -->
    <xsl:copy>
        <xsl:for-each select="1 to $columns">
            <xsl:variable name="low" select="(. - 1) * $col-limit" />
            <xsl:variable name="high" select=". * $col-limit" />
            <xsl:element name="column{.}">
                <xsl:copy-of select="$groups/group[$low lt @cumulative-size and @cumulative-size le $high]"/>
            </xsl:element>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

根据您的输入示例,结果将是:

Given your input example, the result will be:

<?xml version="1.0" encoding="UTF-8"?>
<countries>
   <column1>
      <group name="A" cumulative-size="2">
         <country index="1">
            <name>Argentina</name>
         </country>
         <country index="2" x="AU">
            <name>Australia</name>
         </country>
      </group>
      <group name="C" cumulative-size="3">
         <country index="3">
            <name>Chile</name>
         </country>
      </group>
      <group name="I" cumulative-size="5">
         <country index="4">
            <name>India</name>
         </country>
         <country index="5">
            <name>Indonesia</name>
         </country>
      </group>
   </column1>
   <column2>
      <group name="K" cumulative-size="6">
         <country index="6">
            <name>Kenya</name>
         </country>
      </group>
      <group name="L" cumulative-size="7">
         <country index="7">
            <name>Latvia</name>
         </country>
      </group>
      <group name="N" cumulative-size="8">
         <country index="8">
            <name>New Zeland</name>
         </country>
      </group>
      <group name="S" cumulative-size="9">
         <country index="9">
            <name>Singapore</name>
         </country>
      </group>
      <group name="T" cumulative-size="10">
         <country index="10">
            <name>Tunisia</name>
         </country>
      </group>
   </column2>
   <column3>
      <group name="U" cumulative-size="12">
         <country index="11">
            <name>UK</name>
         </country>
         <country index="12">
            <name>USA</name>
         </country>
      </group>
      <group name="Z" cumulative-size="13">
         <country index="13">
            <name>Zambia</name>
         </country>
      </group>
   </column3>
</countries>

当然,在实际的实现中,你会想在这里使用 xsl-apply-templates 而不是 xsl:copy-of :

Of course, in the real implementation, you will want use xsl-apply-templates instead of xsl:copy-of here:

<xsl:copy-of select="$groups/group[$low lt @cumulative-size and @cumulative-size le $high]"/>

删除脚手架"并根据您的喜好格式化输出.

to remove the "scaffolding" and format the output to your liking.

这篇关于从 xml 分组调整字母索引以使列相等的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆