如何对XLS模板中多个for-each分组的输出结果进行排序
多XDO for-each分组输出统一排序解决方案
你当前使用的是Oracle BI Publisher(原XDO)Excel模板,两个for-each分组分别输出离职数据行和缺勤余额数据行,要对所有生成的行统一排序,以下是可行方案:
方案1:预处理XML数据源(最推荐)
直接在XML数据生成逻辑中,将Termination_Details和Absence_Balance_Details两个节点集合并为同一个统一行节点集,给每行标记行类型,后续模板仅用1个for-each遍历合并后的节点,直接添加<xsl:sort>规则即可完成全量排序,实现成本最低、排序逻辑最稳定。方案2:模板层合并节点集排序(无需修改数据源)
如果无法调整XML生成逻辑,可直接修改模板的分组逻辑,删除原有两个独立for-each分组,改用XPath并集操作符合并两个节点集后统一遍历排序:- 替换原有两个分组的for-each定义为以下代码,按实际排序需求调整sort规则:
注意:调整字段的相对路径为通用路径,推荐用<!-- 合并两个节点集统一遍历 --> <xsl:for-each select=".//Termination_Details[Termination_Date/text() != ''] | .//Absence_Balance_Details[Absence_Accrual_Entry_ID/text() != '']"> <!-- 示例按人员编号升序排序,可替换为你需要的排序字段,data-type可选text/number/date --> <xsl:sort select="ancestor::Assignment_Details/Person_Number" data-type="text" order="ascending"/> <!-- 按节点类型输出对应字段 --> <xsl:choose> <xsl:when test="name() = 'Termination_Details'"> <!-- 此处放原离职分组的字段定义,比如日期、离职动作等 --> <?concat(substring(Termination_Date,9,2),'-',substring(Termination_Date,6,2),'-',substring(Termination_Date,1,4))?> <?Termination_Action?> <?Termination_Reason?> <!-- 缺勤相关字段留空即可 --> </xsl:when> <xsl:when test="name() = 'Absence_Balance_Details'"> <!-- 此处放原缺勤分组的字段定义,比如余额、计划等 --> <?sum(Absence_Balance)?> <?Absence_Plan?> <?Absence_UOM?> <!-- 离职相关字段留空即可 --> </xsl:when> </xsl:choose> <!-- 公共字段直接输出,比如人员编号、 payroll ID --> <?ancestor::Assignment_Details/Person_Number?> <?ancestor::PAYROLL_ACTION_ID?> </xsl:for-each>ancestor轴向上查找公共父节点取公共字段,避免两类节点相对路径不一致取值失败方案3:Excel后置排序(无需修改模板逻辑)
如果不想调整XDO模板的遍历逻辑,可直接在Excel模板中提前配置输出区域的自动排序规则:选中所有输出行对应的列,在Excel中设置「自定义排序」规则保存即可,BI Publisher生成报告时会保留Excel的原生配置,打开报告后自动完成排序,适合临时需求快速实现。
你提供的XDO元数据示例参考:
XDO_?XDOFIELD24? <?../../../../Assignment_Details/Person_Number?> XDO_?XDOFIELD26? <?concat(substring(../Termination_Date,9,2),'-',substring(../Termination_Date,6,2),'-',substring(../Termination_Date,1,4))?> XDO_?XDOFIELD27? <?../Termination_Action?> XDO_?XDOFIELD28? <?../Termination_Reason?> XDO_GROUP_?XDOG3? <xsl:for-each select=".//Termination_Details/Termination_Date[text() != '']"> </xsl:for-each> XDO_?XDOFIELD29? <?sum(../Absence_Balance)?> XDO_?XDOFIELD30? <?../Absence_Plan?> XDO_?XDOFIELD31? <?../Absence_UOM?> XDO_?XDOFIELD32? <?../../../../../../../../PAYROLL_ACTION_ID?> XDO_?XDOFIELD33? <?../../../../Assignment_Details/Person_Number?> XDO_GROUP_?XDOG4? <xsl:for-each select=".//Absence_Balance_Details/Absence_Accrual_Entry_ID[text() != '']"> </xsl:for-each>
内容的提问来源于stack exchange,提问作者jorishaak
相关产品推荐
相关产品推荐

