xpath 或 xslt (1.0) 在具有任意长度块的网格中查找最大行数

xpath or xslt (1.0) to find max number of rows in a grid with blocks of arbitrary length

上下文和终极objective

考虑下面的 XML 应该在图像中创建网格。每个 col 元素代表一个具有宽度和长度的单元格(无论是空单元格还是包含区域)。对于给定的块,起始行(纬度)是已知的,结束行不是。 请注意,没有 <row latitude="6"/>,因为该行已经作为 Desert StatesDeep South 块的一部分用完了。同样,第 3 行缺少 <col timezone="PDT"/>,因为该单元格已被 North West.

占用

我需要知道制作最终网格需要多少行。在这个例子中,我需要 10 行。

问题

我目前的方法是计算出长度总和最大的时区。

sum(//col[@timezone='EDT']/@length)

上面的 xpath 的问题是时区在这里是硬编码的(在实际应用程序中实际上是一个具有大量可能值的轴)。 我试过键和 muenchian 分组但无济于事。

我可以使用什么 xpath 1.0 或 xslt 1.0?

XML

<rows>
    <row latitude="1">
        <cols>
            <col timezone="PDT"  width="1" length="1">Canada</col>
            <col timezone="CDT"  width="1" length="1">Canada</col>
            <col timezone="EDT"  width="1" length="1">Canada</col>
        </cols>
    </row>
    <row latitude="2">
        <cols>
            <col timezone="PDT" width="1" length="2">North West</col>
            <col timezone="CDT" width="1" length="1"></col>
            <col timezone="EDT" width="1" length="1"></col>
        </cols>
    </row>
    <row latitude="3">
        <cols>
            <col timezone="CDT"  width="1" length="1"></col>
            <col timezone="EDT"  width="1" length="2">NY/NJ</col>
        </cols>
    </row>
    <row latitude="4">
        <cols>
            <col timezone="PDT" width="1" length="3">Desert States</col>
            <col timezone="CDT" width="1" length="1"></col>
        </cols>
    </row>
    <row latitude="5">
        <cols>
            <col timezone="CDT"  width="2" length="6">Deep South / Bahamas</col>
            <col timezone="EDT"  width="2" length="6">Deep South / Bahamas</col>
        </cols>
    </row>
    <row latitude="7">
        <cols>
            <col timezone="PDT" width="1" length="2">California</col>
        </cols>
    </row>
</rows>

如果(正如我认为)您想知道任何时区的length的最大总和,您需要将col元素分组他们的时区,按总和对组进行排序,并获得第一个(或最后一个,取决于排序顺序)组的总和值。

这是一个例子:

XSLT 1.0

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

<xsl:key name="col-by-TZ" match="col" use="@timezone" />

<xsl:template match="/rows">
    <xsl:variable name="n">
        <xsl:for-each select="row/cols/col[count(. | key('col-by-TZ', @timezone)[1]) = 1]">
            <xsl:sort select="sum(key('col-by-TZ', @timezone)/@length)" data-type="number" order="descending"/>
            <xsl:if test="position()=1">
                <xsl:value-of select="sum(key('col-by-TZ', @timezone)/@length)"/>
            </xsl:if>
        </xsl:for-each>
    </xsl:variable>
    
    <output>
        <test>
            <xsl:value-of select="$n"/>
        </test>
    </output>
</xsl:template>

</xsl:stylesheet>

test 部分替换为您要使用 $n 变量应用的实际逻辑。