不同元素代码的计数应显示在末尾

问题描述 投票:0回答:2

我总共有 10 个

Detail
元素,如下所示,因为我想根据指标
Code
值拆分和排列
Plan
元素值。

<Details>
    <Detail>
        <Code>001</Code>
        <Type>Alt</Type>
        <Plan>N</Plan>
    </Detail>
    <Detail>
        <Code>002</Code>
        <Type>Alt</Type>
        <Plan>N</Plan>
    </Detail>
    <Detail>
        <Code>003</Code>
        <Type>Alt</Type>
        <Plan>N</Plan>
    </Detail>
    <Detail>
        <Code>004</Code>
        <Type>Alt</Type>
        <Plan>N</Plan>
    </Detail>
    <Detail>
        <Code>005</Code>
        <Type>Alt</Type>
        <Plan>N</Plan>
    </Detail>
    <Detail>
        <Code>006</Code>
        <Type>Alt</Type>
        <Plan>Y</Plan>
    </Detail>
    <Detail>
        <Code>007</Code>
        <Type>Alt</Type>
        <Plan>Y</Plan>
    </Detail>
    <Detail>
        <Code>008</Code>
        <Type>Alt</Type>
        <Plan>N</Plan>
    </Detail>
    <Detail>
        <Code>009</Code>
        <Type>Alt</Type>
        <Plan>N</Plan>
    </Detail>
    <Detail>
        <Code>010</Code>
        <Type>Alt</Type>
        <Plan>N</Plan>
    </Detail>
</Details>

每页我只需要 5 个代码或行来允许,因为我希望

Plan='N'
代码应该放在第一位,
Plan='Y'
代码应该放在下面,我已经尝试了下面的代码

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" version="3.0" exclude-result-prefixes="xs">

<xsl:template match="Details">
    <xsl:call-template name="Table_Left">
        <xsl:with-param name="start_row" as="xs:integer">1</xsl:with-param>
        <xsl:with-param name="end_row" as="xs:integer">10</xsl:with-param>
    </xsl:call-template>
</xsl:template>

<xsl:template name="Table_Left">
    <xsl:param name="start_row" as="xs:integer">0</xsl:param>
    <xsl:param name="end_row" as="xs:integer">0</xsl:param>
    <xsl:variable name="Details" select="Details"/>
    <xsl:variable name="total_rows">
        <xsl:value-of select="count($Details//Detail[Type = 'Alt'])"/>
    </xsl:variable>
    <xsl:variable name="sorted_plans_alt" as="element()">
        <sorted_plans>
            <xsl:for-each select="$Details//Detail[Type = 'Alt']">
                <xsl:sort select=".//Detail[Type = 'Alt']"
                        order="ascending" data-type="number"/>
                <xsl:sequence select="."/>
            </xsl:for-each>
        </sorted_plans>
    </xsl:variable>
    <xsl:variable name="plans_subset">
        <xsl:sequence
                select="
                subsequence($sorted_plans_alt//Detail[Type = 'Alt'], $start_row, $end_row)"
            />
    </xsl:variable>
    <xsl:variable name="preceding_plan" as="element()">
        <preceding_plan>
            <xsl:choose>
                <xsl:when test="$start_row = 1">
                    <empty/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:sequence
                            select="subsequence($sorted_plans_alt//Detail[Type = 'Alt'], $start_row - 1, 1)"
                        />
                </xsl:otherwise>
            </xsl:choose>
        </preceding_plan>
    </xsl:variable>
    <xsl:variable name="rows_to_output" as="xs:integer">
        <xsl:variable name="number_of_r_plans" as="xs:integer">
            <xsl:value-of
                    select="count($Details//Detail[Type = 'Alt'])"/>
        </xsl:variable>
        <xsl:choose>
            <xsl:when test="$number_of_r_plans > 0">
                <xsl:value-of select="$end_row - 5"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$end_row"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>
    <xsl:variable name="left_table" as="element()">
        <xsl:for-each select="($plans_subset//Detail[Type = 'Alt'][Plan='N'])[position() &lt;= $rows_to_output]">
            <xsl:value-of select="current()/Code"/>
        </xsl:for-each>
        <xsl:for-each select="($plans_subset//Detail[Type = 'Alt'][Plan='Y'])[position() &lt;= $rows_to_output]">
            <xsl:value-of select="current()/Code"/>
        </xsl:for-each>
    </xsl:variable>
    <xsl:variable name="right_table">
        <topic id="topic_1" xml:lang="en-US">
            <xsl:apply-templates select="$left_table/*"/>
        </topic>
    </xsl:variable>
    <xsl:sequence select="$right_table"/>
    <xsl:choose>
        <xsl:when test="$start_row + $rows_to_output &lt;= $total_rows">
            <xsl:call-template name="Table_Left">
                <xsl:with-param name="start_row" as="xs:integer"
                        select="$start_row + $rows_to_output"/>
                <xsl:with-param name="end_row" as="xs:integer" select="$end_row"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:when test="$start_row = 999"/>
    </xsl:choose>
</xsl:template>
 </xsl:stylesheet>

在下面的输出中,我在第一页中得到 7 个代码(即使在 xsl 中提到,每页也只有 5 个代码)。但我也收到了

Plan='Y'
(006 和 007)代码。

1st page    2nd page
001         008 
002         009
003         010
004         
005         
006
007

预期输出如下,第一页有 5 个代码,第二页有剩余代码。我需要

Plan=N
代码应该放在第一位,
Plan=Y
代码应该放在后面

1st page    2nd page
001         008 
002         009
003         010
004         006
005         007
     
xml xslt xslt-2.0 xslt-3.0
2个回答
0
投票

预期输出的格式不清楚。

尝试以下方法:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>

<xsl:template match="/Details">
    <!-- sort plan N first -->
    <xsl:variable name="sorted">
        <xsl:perform-sort>
            <xsl:sort select="Plan='Y'"/>
            <xsl:sequence select="Detail"/>
        </xsl:perform-sort>     
    </xsl:variable>
    <!-- output in groups of 5 per page -->
    <output>
        <xsl:for-each-group select="$sorted/Detail" group-adjacent="(position() - 1) idiv 5">
            <page>
                <xsl:copy-of select="current-group()/Code"/>
            </page>
        </xsl:for-each-group>
    </output>   
</xsl:template>

</xsl:stylesheet>

使用提供的输入,输出将是:

<?xml version="1.0" encoding="UTF-8"?>
<output>
   <page>
      <Code>001</Code>
      <Code>002</Code>
      <Code>003</Code>
      <Code>004</Code>
      <Code>005</Code>
   </page>
   <page>
      <Code>008</Code>
      <Code>009</Code>
      <Code>010</Code>
      <Code>006</Code>
      <Code>007</Code>
   </page>
</output>

0
投票

我不清楚你到底想要什么输出,但这里有一些关于你的代码的观察结果,其中一些纯粹是风格上的。

<xsl:with-param name="start_row" as="xs:integer">1</xsl:with-param>

使用

<xsl:with-param name="start_row" as="xs:integer" select="1"/>

它避免了类型转换(从文本节点到整数)。有些人主张始终使用

as
子句,但我会将其留在这里,因为很明显
select="1"
会给您一个
xs:integer

<xsl:variable name="total_rows">
    <xsl:value-of select="count($Details//Detail[Type = 'Alt'])"/>
</xsl:variable>

使用

<xsl:variable name="total_rows" select="count($Details/Detail[Type = 'Alt'])"/>

您确实不想在这里构建 XML 文档,您想计算一个整数。

当您知道

//
元素将是
Detail
的直接子元素时,搜索所有后代 (
Details
) 是没有意义的。

<xsl:for-each select="$Details//Detail[Type = 'Alt']">
                <xsl:sort select=".//Detail[Type = 'Alt']"

这是错误的。排序键是相对于您要排序的元素计算的,您的选择表达式不会选择任何内容。我不知道如何纠正它,因为我不知道你真正想要排序的内容。

<xsl:variable name="left_table" as="element()">
    <xsl:for-each select="($plans_subset//Detail[Type = 'Alt'][Plan='N'])[position() &lt;= $rows_to_output]">
        <xsl:value-of select="current()/Code"/>
    </xsl:for-each>
    <xsl:for-each select="($plans_subset//Detail[Type = 'Alt'][Plan='Y'])[position() &lt;= $rows_to_output]">
        <xsl:value-of select="current()/Code"/>
    </xsl:for-each>
</xsl:variable>

这是错误的,因为您的变量将由文本节点组成(由

xsl:value-of
生成,而不是元素)。也许您有意
xsl:copy-of
current()/Code
Code
的一种冗长说法。

恐怕这些都是细节问题,我怀疑我只见树木不见森林。我怀疑有一些更根本的问题;我不明白你想要实现什么,但我在需求中没有看到任何表明递归命名模板是实现它的适当方法。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.