【问题标题】:Grouping inside for-each based on child element values in xslt 2.0基于 xslt 2.0 中的子元素值在 for-each 内分组
【发布时间】:2022-01-12 20:56:22
【问题描述】:

我有一个如下的 XML -

<Page14 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:statutorytype="us-stat-2020-annual-stmt-pc"
        xmlns:xbrli="http://www.xbrl.org/2001/instance"
        xmlns:iso4217="http://www.xe.com/iso4217.htm"
        xmlns:stat="urn:www-iasa-org/tempuri">
      <RegionRow>
      <Region>HI</Region>
      <EachUniqueCombo>
         <CurrentGroup>20000|16 Workers' Compensation|IBNR Loss Reserves|Pooled</CurrentGroup>
         <LedgerAccount>20000</LedgerAccount>
         <LOB>16 Workers' Compensation</LOB>
         <SpendCategory>IBNR Loss Reserves</SpendCategory>
         <PooledWorktag>Pooled</PooledWorktag>
         <Sum>-31</Sum>
      </EachUniqueCombo>
      <EachUniqueCombo>
         <CurrentGroup>20100|16 Workers' Compensation|IBNR ALAE D&amp;CC Reserves|Pooled</CurrentGroup>
         <LedgerAccount>20100</LedgerAccount>
         <LOB>16 Workers' Compensation</LOB>
         <SpendCategory>IBNR ALAE D&amp;CC Reserves</SpendCategory>
         <PooledWorktag>Pooled</PooledWorktag>
         <Sum>-1</Sum>
      </EachUniqueCombo>
      <EachUniqueCombo>
         <CurrentGroup>24000|16 Workers' Compensation||Pooled</CurrentGroup>
         <LedgerAccount>24000</LedgerAccount>
         <LOB>16 Workers' Compensation</LOB>
         <SpendCategory/>
         <PooledWorktag>Pooled</PooledWorktag>
         <Sum>-45.13</Sum>
      </EachUniqueCombo>
      <EachUniqueCombo>
         <CurrentGroup>40000|16 Workers' Compensation||Pooled</CurrentGroup>
         <LedgerAccount>40000</LedgerAccount>
         <LOB>16 Workers' Compensation</LOB>
         <SpendCategory/>
         <PooledWorktag>Pooled</PooledWorktag>
         <Sum>-65</Sum>
      </EachUniqueCombo>
      <EachUniqueCombo>
         <CurrentGroup>40010|16 Workers' Compensation||Pooled</CurrentGroup>
         <LedgerAccount>40010</LedgerAccount>
         <LOB>16 Workers' Compensation</LOB>
         <SpendCategory/>
         <PooledWorktag>Pooled</PooledWorktag>
         <Sum>-5.34</Sum>
      </EachUniqueCombo>
      <EachUniqueCombo>
         <CurrentGroup>50000|16 Workers' Compensation|Change in IBNR Loss Reserves|Pooled</CurrentGroup>
         <LedgerAccount>50000</LedgerAccount>
         <LOB>16 Workers' Compensation</LOB>
         <SpendCategory>Change in IBNR Loss Reserves</SpendCategory>
         <PooledWorktag>Pooled</PooledWorktag>
         <Sum>-16</Sum>
      </EachUniqueCombo>
      <EachUniqueCombo>
         <CurrentGroup>50100|16 Workers' Compensation|Change in IBNR ALAE D&amp;CC Reserves|Pooled</CurrentGroup>
         <LedgerAccount>50100</LedgerAccount>
         <LOB>16 Workers' Compensation</LOB>
         <SpendCategory>Change in IBNR ALAE D&amp;CC Reserves</SpendCategory>
         <PooledWorktag>Pooled</PooledWorktag>
         <Sum>1</Sum>
      </EachUniqueCombo>
      <EachUniqueCombo>
         <CurrentGroup>51000|16 Workers' Compensation|Change in Commission Reserves|Pooled</CurrentGroup>
         <LedgerAccount>51000</LedgerAccount>
         <LOB>16 Workers' Compensation</LOB>
         <SpendCategory>Change in Commission Reserves</SpendCategory>
         <PooledWorktag>Pooled</PooledWorktag>
         <Sum>-1</Sum>
      </EachUniqueCombo>
      <EachUniqueCombo>
         <CurrentGroup>51000|16 Workers' Compensation|Paid Commissions|Pooled</CurrentGroup>
         <LedgerAccount>51000</LedgerAccount>
         <LOB>16 Workers' Compensation</LOB>
         <SpendCategory>Paid Commissions</SpendCategory>
         <PooledWorktag>Pooled</PooledWorktag>
         <Sum>-0.05</Sum>
      </EachUniqueCombo>
      <EachUniqueCombo>
         <CurrentGroup>20000|17.1 Other Liability - Bodily Injury, Occurrence|IBNR Loss Reserves|Pooled</CurrentGroup>
         <LedgerAccount>20000</LedgerAccount>
         <LOB>17.1 Other Liability - Bodily Injury, Occurrence</LOB>
         <SpendCategory>IBNR Loss Reserves</SpendCategory>
         <PooledWorktag>Pooled</PooledWorktag>
         <Sum>-28</Sum>
      </EachUniqueCombo>
      <EachUniqueCombo>
         <CurrentGroup>20100|17.1 Other Liability - Bodily Injury, Occurrence|IBNR ALAE D&amp;CC Reserves|Pooled</CurrentGroup>
         <LedgerAccount>20100</LedgerAccount>
         <LOB>17.1 Other Liability - Bodily Injury, Occurrence</LOB>
         <SpendCategory>IBNR ALAE D&amp;CC Reserves</SpendCategory>
         <PooledWorktag>Pooled</PooledWorktag>
         <Sum>135</Sum>
      </EachUniqueCombo>
      <EachUniqueCombo>
         <CurrentGroup>24000|17.1 Other Liability - Bodily Injury, Occurrence||Pooled</CurrentGroup>
         <LedgerAccount>24000</LedgerAccount>
         <LOB>17.1 Other Liability - Bodily Injury, Occurrence</LOB>
         <SpendCategory/>
         <PooledWorktag>Pooled</PooledWorktag>
         <Sum>19.17</Sum>
      </EachUniqueCombo>
      <EachUniqueCombo>
         <CurrentGroup>40000|17.1 Other Liability - Bodily Injury, Occurrence||Pooled</CurrentGroup>
         <LedgerAccount>40000</LedgerAccount>
         <LOB>17.1 Other Liability - Bodily Injury, Occurrence</LOB>
         <SpendCategory/>
         <PooledWorktag>Pooled</PooledWorktag>
         <Sum>22</Sum>
      </EachUniqueCombo>
      <EachUniqueCombo>
         <CurrentGroup>40010|17.1 Other Liability - Bodily Injury, Occurrence||Pooled</CurrentGroup>
         <LedgerAccount>40010</LedgerAccount>
         <LOB>17.1 Other Liability - Bodily Injury, Occurrence</LOB>
         <SpendCategory/>
         <PooledWorktag>Pooled</PooledWorktag>
         <Sum>-21.24</Sum>
      </EachUniqueCombo>
      <EachUniqueCombo>
         <CurrentGroup>50000|17.1 Other Liability - Bodily Injury, Occurrence|Change in IBNR Loss Reserves|Pooled</CurrentGroup>
         <LedgerAccount>50000</LedgerAccount>
         <LOB>17.1 Other Liability - Bodily Injury, Occurrence</LOB>
         <SpendCategory>Change in IBNR Loss Reserves</SpendCategory>
         <PooledWorktag>Pooled</PooledWorktag>
         <Sum>-261</Sum>
      </EachUniqueCombo>
      <EachUniqueCombo>
         <CurrentGroup>50100|17.1 Other Liability - Bodily Injury, Occurrence|Change in IBNR ALAE D&amp;CC Reserves|Pooled</CurrentGroup>
         <LedgerAccount>50100</LedgerAccount>
         <LOB>17.1 Other Liability - Bodily Injury, Occurrence</LOB>
         <SpendCategory>Change in IBNR ALAE D&amp;CC Reserves</SpendCategory>
         <PooledWorktag>Pooled</PooledWorktag>
         <Sum>-135</Sum>
      </EachUniqueCombo>
      <EachUniqueCombo>
         <CurrentGroup>51000|17.1 Other Liability - Bodily Injury, Occurrence|Change in Commission Reserves|Pooled</CurrentGroup>
         <LedgerAccount>51000</LedgerAccount>
         <LOB>17.1 Other Liability - Bodily Injury, Occurrence</LOB>
         <SpendCategory>Change in Commission Reserves</SpendCategory>
         <PooledWorktag>Pooled</PooledWorktag>
         <Sum>1</Sum>
      </EachUniqueCombo>
      <EachUniqueCombo>
         <CurrentGroup>51000|17.1 Other Liability - Bodily Injury, Occurrence|Paid Commissions|Pooled</CurrentGroup>
         <LedgerAccount>51000</LedgerAccount>
         <LOB>17.1 Other Liability - Bodily Injury, Occurrence</LOB>
         <SpendCategory>Paid Commissions</SpendCategory>
         <PooledWorktag>Pooled</PooledWorktag>
         <Sum>-3.3</Sum>
      </EachUniqueCombo>
      <EachUniqueCombo>
         <CurrentGroup>20000|17.1 Other Liability - Physical Damage, Occurrence|IBNR Loss Reserves|Pooled</CurrentGroup>
         <LedgerAccount>20000</LedgerAccount>
         <LOB>17.1 Other Liability - Physical Damage, Occurrence</LOB>
         <SpendCategory>IBNR Loss Reserves</SpendCategory>
         <PooledWorktag>Pooled</PooledWorktag>
         <Sum>1</Sum>
      </EachUniqueCombo>
      <EachUniqueCombo>
         <CurrentGroup>50000|17.1 Other Liability - Physical Damage, Occurrence|Change in IBNR Loss Reserves|Pooled</CurrentGroup>
         <LedgerAccount>50000</LedgerAccount>
         <LOB>17.1 Other Liability - Physical Damage, Occurrence</LOB>
         <SpendCategory>Change in IBNR Loss Reserves</SpendCategory>
         <PooledWorktag>Pooled</PooledWorktag>
         <Sum>-1</Sum>
      </EachUniqueCombo>
      <EachUniqueCombo>
         <CurrentGroup>20000|24 Surety|IBNR Loss Reserves|Pooled</CurrentGroup>
         <LedgerAccount>20000</LedgerAccount>
         <LOB>24 Surety</LOB>
         <SpendCategory>IBNR Loss Reserves</SpendCategory>
         <PooledWorktag>Pooled</PooledWorktag>
         <Sum>-458</Sum>
      </EachUniqueCombo>
      <EachUniqueCombo>
         <CurrentGroup>20100|24 Surety|IBNR ALAE D&amp;CC Reserves|Pooled</CurrentGroup>
         <LedgerAccount>20100</LedgerAccount>
         <LOB>24 Surety</LOB>
         <SpendCategory>IBNR ALAE D&amp;CC Reserves</SpendCategory>
         <PooledWorktag>Pooled</PooledWorktag>
         <Sum>-24</Sum>
      </EachUniqueCombo>
      <EachUniqueCombo>
         <CurrentGroup>24000|24 Surety||Pooled</CurrentGroup>
         <LedgerAccount>24000</LedgerAccount>
         <LOB>24 Surety</LOB>
         <SpendCategory/>
         <PooledWorktag>Pooled</PooledWorktag>
         <Sum>354.28</Sum>
      </EachUniqueCombo>
      <EachUniqueCombo>
         <CurrentGroup>40010|24 Surety||Pooled</CurrentGroup>
         <LedgerAccount>40010</LedgerAccount>
         <LOB>24 Surety</LOB>
         <SpendCategory/>
         <PooledWorktag>Pooled</PooledWorktag>
         <Sum>-819</Sum>
      </EachUniqueCombo>
      <EachUniqueCombo>
         <CurrentGroup>50000|24 Surety|Change in IBNR Loss Reserves|Pooled</CurrentGroup>
         <LedgerAccount>50000</LedgerAccount>
         <LOB>24 Surety</LOB>
         <SpendCategory>Change in IBNR Loss Reserves</SpendCategory>
         <PooledWorktag>Pooled</PooledWorktag>
         <Sum>-292</Sum>
      </EachUniqueCombo>
      <EachUniqueCombo>
         <CurrentGroup>50100|24 Surety|Change in IBNR ALAE D&amp;CC Reserves|Pooled</CurrentGroup>
         <LedgerAccount>50100</LedgerAccount>
         <LOB>24 Surety</LOB>
         <SpendCategory>Change in IBNR ALAE D&amp;CC Reserves</SpendCategory>
         <PooledWorktag>Pooled</PooledWorktag>
         <Sum>24</Sum>
      </EachUniqueCombo>
   </RegionRow>
   <RegionRow>
   <Region>AL</Region>
    ----
   </RegionRow>
   
</Page14>

对于上述 XML,我需要编写一个针对每个 RegionRow 元素和每个区域内运行的 xslt,我需要首先基于 LOB 元素进行分组,然后在此基础上我需要对元素“Sum”进行求和在某些分类账上。

我正在尝试如下编写 xslt -

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:wd="urn:com.workday.report/CR_Page_14_EMC"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:statutorytype="us-stat-2020-annual-stmt-pc"
    xmlns:xbrli="http://www.xbrl.org/2001/instance" xmlns:iso4217="http://www.xe.com/iso4217.htm"
    xmlns:stat="urn:www-iasa-org/tempuri" exclude-result-prefixes=" wd xs" version="2.0">
    
    <xsl:output indent="yes" method="xml"/>
    
    <xsl:variable name="single_quote">
        <xsl:text>'</xsl:text>
    </xsl:variable>
    <xsl:variable name="ampersand">
        <xsl:text>&amp;</xsl:text>
    </xsl:variable>
    
    <xsl:template match="Page14">
        <OutputOfNextXSL>
            <xsl:for-each select="RegionRow">
                <RowData>
                    <Region>
                        <xsl:value-of select="Region"/>
                    </Region>
                    <xsl:for-each-group select="EachUniqueCombo" group-by="EachUniqueCombo[LOB = '24 Surety']">
                        <CellOneAllied>
                            <!-- ledger account xyz, -->
                            <xsl:value-of
                                select="-1 * sum(EachUniqueCombo[LedgerAccount = '40000' or LedgerAccount = '20000']/xs:decimal(Sum))"/>
                            
                        </CellOneAllied>
<CellTwoAllied>
</CellTwoAllied>
---
--
                    </xsl:for-each-group>
<xsl:for-each-group select= EachUniqueCombo group-by=EachUniqueCombo[LOB = '16 Workers' Compensation']">
  <!-- Sum here based on one or multiple ledger accounts-->
</xsl:for-each-group>

分组依据可以基于 1 个 LOB 或多个,类似地,我需要进行总和的分组内的分类帐帐户/支出类别也可以是单个或多个。我无法根据上述分组逻辑获得任何值,然后也无法到达组内的分类帐帐户或支出类别以进行总和。 有人可以帮助实现这一目标吗?

【问题讨论】:

  • 在询问 XSLT 问题时,您需要提供 minimal reproducible example: (1) 输入 XML。 (2) 你的逻辑,以及试图实现它的 XSLT。 (3) 所需的输出,基于上面#1 中的示例 XML。 (4) XSLT 处理器及其对 XSLT 标准的遵从性:1.0、2.0 或 3.0。
  • 我不清楚你想要实现什么,无论是从你的口头描述还是像 xsl:for-each-group select="EachUniqueCombo" group-by="EachUniqueCombo[LOB = '24 Surety']" 这样的代码,因为它选择上下文节点的所有 EachUniqueCombo 子元素作为分组人口和尝试通过由人口中每个项目的EachUniqueCombo[LOB = '24 Surety'] 子元素形成的键对它们进行分组。由于您的 EachUniqueCombo 元素似乎没有嵌套,因此没有任何意义。也许您只是想选择和求和,例如sum(EachUniqueCombo[LOB = '24 Surety']/Sum).

标签: xml xslt xslt-2.0


【解决方案1】:

因此,您只想将相同的“LedgerAccount”-Tag 与每个“RegionRow”-Tag 中的 sum von “Sum”-Tag “分组”

按照 XSLT-Code 会这样:

XSLT

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" exclude-result-prefixes="#all" version="2.0">
  <xsl:output method="xml" encoding="UTF-8"/>
  <xsl:template match="/">
<RegionRow>

  <xsl:for-each select="//RegionRow"> <!-- seach all RegionRow-Tags -->
     <xsl:for-each-group select="./EachUniqueCombo" group-by="LedgerAccount"> <!-- in each RegionRow-Tag group same LedgerAccounts -->
     <xsl:variable name="key" select="current-grouping-key()"/> <!-- save current key in variable "key" to get the right siblings -->
          <EachUniqueCombo>
               <key><xsl:value-of select="$key"/></key>
               <Sum><xsl:value-of select="sum(current-group()/Sum)"/></Sum> <!-- sum of all same LedgerAccounts / get each Sum-Tag, which has a sibling with the current LedgerAccount (key) -->
          </EachUniqueCombo>
     </xsl:for-each-group>
  </xsl:for-each>

</RegionRow>

  </xsl:template>
</xsl:stylesheet>

第一个示例的 XML 输出

<?xml version="1.0" encoding="UTF-8"?>
<RegionRow>
    <EachUniqueCombo>
        <key>20000</key>
        <Sum>-516</Sum>
    </EachUniqueCombo>
    <EachUniqueCombo>
        <key>20100</key>
        <Sum>110</Sum>
    </EachUniqueCombo>
    <EachUniqueCombo>
        <key>24000</key>
        <Sum>328.32</Sum>
    </EachUniqueCombo>
    <EachUniqueCombo>
        <key>40000</key>
        <Sum>-43</Sum>
    </EachUniqueCombo>
    <EachUniqueCombo>
        <key>40010</key>
        <Sum>-845.58</Sum>
    </EachUniqueCombo>
    <EachUniqueCombo>
        <key>50000</key>
        <Sum>-570</Sum>
    </EachUniqueCombo>
    <EachUniqueCombo>
        <key>50100</key>
        <Sum>-110</Sum>
    </EachUniqueCombo>
    <EachUniqueCombo>
        <key>51000</key>
        <Sum>-3.3499999999999996</Sum>
    </EachUniqueCombo>
</RegionRow>

XSLT 包括。分组 LOB 子字符串(前 3 个字符)

<RegionRow>
  <xsl:for-each select="//RegionRow">
     <xsl:for-each-group select="./EachUniqueCombo" group-by="substring(LOB,1,3)">
     <xsl:variable name="LOB-key" select="./LOB"/>
          <EachUniqueCombo>
            <LOB>
               <LOB_SubStr_Value><xsl:value-of select="substring($LOB-key,1,3)"/></LOB_SubStr_Value>
                    <xsl:for-each select="//LedgerAccount[../LOB=$LOB-key]">
                    <xsl:variable name="key" select="."/>
                              <key><xsl:value-of select="$key"/></key>
                              <Sum><xsl:value-of select="sum(current-group()/Sum[../LedgerAccount/text()=$key])"/></Sum> <!-- sum of all same LedgerAccounts in LOB_Substr_Value -->
                    </xsl:for-each>
               </LOB>
          </EachUniqueCombo>
     </xsl:for-each-group>
  </xsl:for-each>
</RegionRow>

输出包括。分组 LOB 子字符串(前 3 个字符)

<?xml version="1.0" encoding="UTF-8"?>
<RegionRow>
    <EachUniqueCombo>
        <LOB>
            <LOB_SubStr_Value>16 </LOB_SubStr_Value>
            <key>20000</key>
            <Sum>-31</Sum>
            <key>20100</key>
            <Sum>-1</Sum>
            <key>24000</key>
            <Sum>-45.13</Sum>
            <key>40000</key>
            <Sum>-65</Sum>
            <key>40010</key>
            <Sum>-5.34</Sum>
            <key>50000</key>
            <Sum>-16</Sum>
            <key>50100</key>
            <Sum>1</Sum>
            <key>51000</key>
            <Sum>-1.05</Sum>
            <key>51000</key>
            <Sum>-1.05</Sum>
        </LOB>
    </EachUniqueCombo>
    <EachUniqueCombo>
        <LOB>
            <LOB_SubStr_Value>17.</LOB_SubStr_Value>
            <key>20000</key>
            <Sum>-28</Sum>
            <key>20100</key>
            <Sum>135</Sum>
            <key>24000</key>
            <Sum>19.17</Sum>
            <key>40000</key>
            <Sum>22</Sum>
            <key>40010</key>
            <Sum>-21.24</Sum>
            <key>50000</key>
            <Sum>-261</Sum>
            <key>50100</key>
            <Sum>-135</Sum>
            <key>51000</key>
            <Sum>-2.3</Sum>
            <key>51000</key>
            <Sum>-2.3</Sum>
        </LOB>
    </EachUniqueCombo>
    <EachUniqueCombo>
        <LOB>
            <LOB_SubStr_Value>24 </LOB_SubStr_Value>
            <key>20000</key>
            <Sum>-458</Sum>
            <key>20100</key>
            <Sum>-24</Sum>
            <key>24000</key>
            <Sum>354.28</Sum>
            <key>40010</key>
            <Sum>-819</Sum>
            <key>50000</key>
            <Sum>-292</Sum>
            <key>50100</key>
            <Sum>24</Sum>
        </LOB>
    </EachUniqueCombo>
</RegionRow>

【讨论】:

  • 嗨@Andreas Hauser,感谢您的帮助。我想要实现的目标如下 - 每个 RegionRow 标签,我需要首先按 LOB 标签分组,这表示对于某些情况,我想按 1 LOB 分组,如“16 工人补偿”,但在某些情况下我必须根据多个 LOB 值进行分组。完成后,我想按 LedgerAccount 标记进行分组,在某些情况下它又是一个值,而对于某些它的多个值,然后在这些标记下进行 Sum 标记的总和。我希望这次我清楚一点。
  • 多个 LOB 的一个示例是“17.1 其他责任 - 人身伤害,事故”和“17.1 其他责任 - 身体伤害,事故”。我需要对从“17.1”开始的所有 LOB 进行分组,然后在 LedgerAccount 上进行分组。
  • 现在我得到了? -- 很好的例子 → 你也可以按子字符串分组 - 例如: ... 在本例中,“for-each-group”只是按 LOB 值中的前 3 个字符分组。 → 这应该适用于您给定的示例。
  • 很抱歉让大家感到困惑,但我不太擅长 xslt 和这种复杂的嵌套逻辑。不过谢谢!
  • for-each-group 内部,我认为您应该在要计算总和的任何地方使用函数current-group(),例如sum(current-group()/Sum),而不是通过键比较重新计算组。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-16
  • 1970-01-01
  • 2021-07-26
  • 2014-05-13
相关资源
最近更新 更多