XSLT 2,按属性和元素进行多个分组

时间:2017-10-16 08:38:17

标签: xslt-2.0 xslt-grouping

我似乎无法根据MaritalStatus管理分组情侣 我已经设法将所有处于关系中的人(“DeFacto”,“已婚”)分组,但无法弄清楚如何将他们分组到不同的家庭。

基本上如果两个人结交一对,他们就会创造一个家庭。家庭姓名将属于家庭中的第一个姓氏,NumberOfAdults将被硬编码为“2”,NumberOfDependants将被加总。

这对夫妇是基于Party.Identifier和Party.MaritalStatus.RelatedEntityRef链接的

我拥有(简化):

<PartySegment>
<Party Type="Guarantor" PrimaryApplicant="No">
    <Identifier>b8b0f908b08e</Identifier>
    <Person Sex="Female" FirstHomeBuyer="No" CustomerOfLender="No">
        <PersonName>
            <NameTitle Value="Lady"/>
            <FirstName>Clemansa</FirstName>
            <Surname>Sanchez</Surname>
        </PersonName>
        <MaritalStatus Status="DeFacto">
            <RelatedEntityRef>ea384b0bf3f5</RelatedEntityRef>
        </MaritalStatus>
        <NumberOfDependents>1</NumberOfDependents>
    </Person>
</Party>
<Party Type="Applicant" PrimaryApplicant="Yes" ExistingCustomerID="1231">
    <Identifier>bd8c65a3ad80</Identifier>
    <Person Sex="Female" FirstHomeBuyer="Yes" CustomerOfLender="Yes">
        <PersonName>
            <NameTitle Value="Mrs"/>
            <FirstName>Cheryl</FirstName>
            <Surname>Bonkers</Surname>
        </PersonName>
        <MaritalStatus Status="Married">
            <RelatedEntityRef>ee84dc9e38ec</RelatedEntityRef>
        </MaritalStatus>
        <NumberOfDependents>2</NumberOfDependents>
    </Person>
</Party>
<Party Type="Guarantor" PrimaryApplicant="No">
    <Identifier>ea384b0bf3f5</Identifier>
    <Person Sex="Male" FirstHomeBuyer="No" CustomerOfLender="No">
        <PersonName>
            <NameTitle Value="Mr"/>
            <FirstName>Greg</FirstName>
            <OtherName>Morty</OtherName>
            <Surname>Sanchez</Surname>
        </PersonName>
        <MaritalStatus Status="DeFacto">
            <RelatedEntityRef>b8b0f908b08e</RelatedEntityRef>
        </MaritalStatus>
        <NumberOfDependents>0</NumberOfDependents>
    </Person>
</Party>
<Party Type="Applicant" PrimaryApplicant="No">
    <Identifier>ee84dc9e38ec</Identifier>
    <Person Sex="Male" FirstHomeBuyer="No" CustomerOfLender="No">
        <PersonName>
            <NameTitle Value="Mr"/>
            <FirstName>Mark</FirstName>
            <Surname>Bonkers</Surname>
        </PersonName>
        <MaritalStatus Status="Married">
            <RelatedEntityRef>bd8c65a3ad80</RelatedEntityRef>
        </MaritalStatus>
        <NumberOfDependents>0</NumberOfDependents>
    </Person>
</Party>
</PartySegment>

欲望输出:

<Household UniqueID="b8b0f908b08e-Household"
                Name="Sanchez Household"
                NumberOfAdults="2"
                NumberOfDependants="1"/>

<Household UniqueID="bd8c65a3ad80-Household"
                Name="Bonkers Household"
                NumberOfAdults="2"
                NumberOfDependants="2"/>

到目前为止(简化):这对一对夫妇有用,因为没有考虑到MaritalStatus.RelatedEntityRef信息

<xsl:template match="PartySegment" mode="Household_Couple">

    <xsl:for-each-group select="Party[Person/MaritalStatus/@Status = ('DeFacto', 'Married')]" group-by="Person/MaritalStatus/@Status = ('DeFacto', 'Married')">
        <xsl:variable name="owner_id" select="Identifier"/>

        <Household UniqueID="{concat(Identifier, '-Household')}" 
            Name="{normalize-space(concat(Person/PersonName/Surname, ' Household'))}"
            NumberOfAdults="{'2'}"
            NumberOfDependants="{if(Person/Dependent) then count(current-group()/Person/Dependent) else if(Person/NumberOfDependents) then sum(current-group()/Person/NumberOfDependents) else '0'}">

            <xsl:apply-templates select="current-group()/Person/Dependent"/>

        </Household>
    </xsl:for-each-group>
</xsl:template>

1 个答案:

答案 0 :(得分:1)

如果你可以转移到XSLT 3.0,那么我认为两个相关标识符的复合分组键sort((Identifier, key('ref', Person/MaritalStatus/RelatedEntityRef)/Identifier))可以解决这个问题:

<xsl:key name="ref" match="Party" use="Identifier"/>

<xsl:template match="PartySegment">
    <xsl:for-each-group select="Party[Person/MaritalStatus/@Status = ('DeFacto', 'Married')]" 
        composite="yes" 
        group-by="sort((Identifier, key('ref', Person/MaritalStatus/RelatedEntityRef)/Identifier))">
        <Household UniqueID="{concat(Identifier, '-Household')}" 
            Name="{normalize-space(concat(Person/PersonName/Surname, ' Household'))}"
            NumberOfAdults="{'2'}"
            NumberOfDependants="{if(Person/Dependent) then count(current-group()/Person/Dependent) else if(Person/NumberOfDependents) then sum(current-group()/Person/NumberOfDependents) else '0'}">



        </Household>
    </xsl:for-each-group>
</xsl:template>

我得到了

<Household UniqueID="b8b0f908b08e-Household"
           Name="Sanchez Household"
           NumberOfAdults="2"
           NumberOfDependants="1"/>
<Household UniqueID="bd8c65a3ad80-Household"
           Name="Bonkers Household"
           NumberOfAdults="2"
           NumberOfDependants="2"/>

这种方式与oXygen内的Saxon 9.8 EE一样。

对于Saxon 9.8 HE,应该可以将其重写为

<xsl:key name="ref" match="Party" use="Identifier"/>

<xsl:template match="PartySegment">
    <xsl:for-each-group select="Party[Person/MaritalStatus/@Status = ('DeFacto', 'Married')]" 
        composite="yes" 
        group-by="Identifier | key('ref', Person/MaritalStatus/RelatedEntityRef)/Identifier">
        <Household UniqueID="{concat(Identifier, '-Household')}" 
            Name="{normalize-space(concat(Person/PersonName/Surname, ' Household'))}"
            NumberOfAdults="{'2'}"
            NumberOfDependants="{if(Person/Dependent) then count(current-group()/Person/Dependent) else if(Person/NumberOfDependents) then sum(current-group()/Person/NumberOfDependents) else '0'}">



        </Household>
    </xsl:for-each-group>
</xsl:template>

对于我们没有复合键的XSLT 2.0,我们需要确保用两个组件构造一个键:

<xsl:template match="PartySegment">
    <xsl:for-each-group select="Party[Person/MaritalStatus/@Status = ('DeFacto', 'Married')]" 
        group-by="string-join((Identifier | key('ref', Person/MaritalStatus/RelatedEntityRef)/Identifier), '|')">
        <Household UniqueID="{concat(Identifier, '-Household')}" 
            Name="{normalize-space(concat(Person/PersonName/Surname, ' Household'))}"
            NumberOfAdults="{'2'}"
            NumberOfDependants="{if(Person/Dependent) then count(current-group()/Person/Dependent) else if(Person/NumberOfDependents) then sum(current-group()/Person/NumberOfDependents) else '0'}">



        </Household>
    </xsl:for-each-group>
</xsl:template>