รวมองค์ประกอบที่จัดกลุ่มใน XSL 1.0

XSL กำลังทำให้ฉันแทบบ้า และฉันหวังว่าจะมีคนช่วยฉันในเรื่องนี้ รหัสพร้อมสำหรับการคัดลอกและวาง

ฉันกำลังจัดกลุ่มโดยใช้ XSL 1.0 และฉันต้องการหาผลรวมขององค์ประกอบ 'จำนวน' ที่จัดกลุ่มทั้งหมด

ข้อมูลของฉันมีลักษณะเช่นนี้

<CustInvoiceTable class="entity">
    <McsCmBilCalcInvoiceLine class="entity">
        <Amount>0.05</Amount>
        <ItemId>ITM-0000088</ItemId>
        <McsCmBilProductItem class="entity">
            <CgiBundleLines>1</CgiBundleLines>
        </McsCmBilProductItem>
    </McsCmBilCalcInvoiceLine>
    <McsCmBilCalcInvoiceLine class="entity">
        <Amount>0.07</Amount>
        <ItemId>ITM-0000088</ItemId>
        <McsCmBilProductItem class="entity">
            <CgiBundleLines>1</CgiBundleLines>
        </McsCmBilProductItem>
    </McsCmBilCalcInvoiceLine>
    <McsCmBilCalcInvoiceLine class="entity">
        <Amount>0.16</Amount>
        <ItemId>ITM-0000091</ItemId>
        <McsCmBilProductItem class="entity">
            <CgiBundleLines>1</CgiBundleLines>
        </McsCmBilProductItem>
    </McsCmBilCalcInvoiceLine>
    <McsCmBilCalcInvoiceLine class="entity">
        <Amount>0.22</Amount>
        <ItemId>ITM-0000091</ItemId>
        <McsCmBilProductItem class="entity">
            <CgiBundleLines>1</CgiBundleLines>
        </McsCmBilProductItem>
    </McsCmBilCalcInvoiceLine>
    <McsCmBilCalcInvoiceLine class="entity">
        <Amount>1.33</Amount>
        <ItemId>ITM-0000098</ItemId>
        <McsCmBilProductItem class="entity">
            <CgiBundleLines>1</CgiBundleLines>
        </McsCmBilProductItem>
    </McsCmBilCalcInvoiceLine>
    <McsCmBilCalcInvoiceLine class="entity">
        <Amount>1.82</Amount>
        <ItemId>ITM-0000098</ItemId>
        <McsCmBilProductItem class="entity">
            <CgiBundleLines>1</CgiBundleLines>
        </McsCmBilProductItem>
    </McsCmBilCalcInvoiceLine>
    <McsCmBilCalcInvoiceLine class="entity">
        <Amount>0.01</Amount>
        <ItemId>ITM-0000086</ItemId>
        <McsCmBilProductItem class="entity">
            <CgiBundleLines>1</CgiBundleLines>
        </McsCmBilProductItem>
    </McsCmBilCalcInvoiceLine>
    <McsCmBilCalcInvoiceLine class="entity">
        <Amount>0.01</Amount>
        <ItemId>ITM-0000086</ItemId>
        <McsCmBilProductItem class="entity">
            <CgiBundleLines>1</CgiBundleLines>
        </McsCmBilProductItem>
    </McsCmBilCalcInvoiceLine>
    <McsCmBilCalcInvoiceLine class="entity">
        <Amount>0.05</Amount>
        <ItemId>ITM-0000062</ItemId>
        <McsCmBilProductItem class="entity">
            <CgiBundleLines>2</CgiBundleLines>
        </McsCmBilProductItem>
    </McsCmBilCalcInvoiceLine>
    <McsCmBilCalcInvoiceLine class="entity">
        <Amount>0.06</Amount>
        <ItemId>ITM-0000062</ItemId>
        <McsCmBilProductItem class="entity">
            <CgiBundleLines>2</CgiBundleLines>
        </McsCmBilProductItem>
    </McsCmBilCalcInvoiceLine>
    <McsCmBilCalcInvoiceLine class="entity">
        <Amount>0.02</Amount>
        <ItemId>ITM-0000111</ItemId>
        <McsCmBilProductItem class="entity">
            <CgiBundleLines>1</CgiBundleLines>
        </McsCmBilProductItem>
    </McsCmBilCalcInvoiceLine>
    <McsCmBilCalcInvoiceLine class="entity">
        <Amount>0.02</Amount>
        <ItemId>ITM-0000111</ItemId>
        <McsCmBilProductItem class="entity">
            <CgiBundleLines>1</CgiBundleLines>
        </McsCmBilProductItem>
    </McsCmBilCalcInvoiceLine>
    <McsCmBilCalcInvoiceLine class="entity">
        <Amount>0.06</Amount>
        <ItemId>ITM-0000089</ItemId>
        <McsCmBilProductItem class="entity">
            <CgiBundleLines>1</CgiBundleLines>
        </McsCmBilProductItem>
    </McsCmBilCalcInvoiceLine>
    <McsCmBilCalcInvoiceLine class="entity">
        <Amount>0.08</Amount>
        <ItemId>ITM-0000089</ItemId>
        <McsCmBilProductItem class="entity">
            <CgiBundleLines>1</CgiBundleLines>
        </McsCmBilProductItem>
    </McsCmBilCalcInvoiceLine>
    <McsCmBilCalcInvoiceLine class="entity">
        <Amount>1.96</Amount>
        <ItemId>ITM-0000092</ItemId>
        <McsCmBilProductItem class="entity">
            <CgiBundleLines>1</CgiBundleLines>
        </McsCmBilProductItem>
    </McsCmBilCalcInvoiceLine>
    <McsCmBilCalcInvoiceLine class="entity">
        <Amount>2.69</Amount>
        <ItemId>ITM-0000092</ItemId>
        <McsCmBilProductItem class="entity">
            <CgiBundleLines>1</CgiBundleLines>
        </McsCmBilProductItem>
    </McsCmBilCalcInvoiceLine>
    <McsCmBilCalcInvoiceLine class="entity">
        <Amount>0.07</Amount>
        <ItemId>ITM-0000101</ItemId>
        <McsCmBilProductItem class="entity">
            <CgiBundleLines>1</CgiBundleLines>
        </McsCmBilProductItem>
    </McsCmBilCalcInvoiceLine>
    <McsCmBilCalcInvoiceLine class="entity">
        <Amount>0.10</Amount>
        <ItemId>ITM-0000101</ItemId>
        <McsCmBilProductItem class="entity">
            <CgiBundleLines>1</CgiBundleLines>
        </McsCmBilProductItem>
    </McsCmBilCalcInvoiceLine>
    <McsCmBilCalcInvoiceLine class="entity">
        <Amount>0.07</Amount>
        <ItemId>ITM-0000102</ItemId>
        <McsCmBilProductItem class="entity">
            <CgiBundleLines>1</CgiBundleLines>
        </McsCmBilProductItem>
    </McsCmBilCalcInvoiceLine>
    <McsCmBilCalcInvoiceLine class="entity">
        <Amount>0.10</Amount>
        <ItemId>ITM-0000102</ItemId>
        <McsCmBilProductItem class="entity">
            <CgiBundleLines>1</CgiBundleLines>
        </McsCmBilProductItem>
    </McsCmBilCalcInvoiceLine>
    <McsCmBilCalcInvoiceLine class="entity">
        <Amount>6.69</Amount>
        <ItemId>ITM-0000083</ItemId>
        <McsCmBilProductItem class="entity">
            <CgiBundleLines>1</CgiBundleLines>
        </McsCmBilProductItem>
    </McsCmBilCalcInvoiceLine>
    <McsCmBilCalcInvoiceLine class="entity">
        <Amount>7.96</Amount>
        <ItemId>ITM-0000083</ItemId>
        <McsCmBilProductItem class="entity">
            <CgiBundleLines>1</CgiBundleLines>
        </McsCmBilProductItem>
    </McsCmBilCalcInvoiceLine>
    <McsCmBilCalcInvoiceLine class="entity">
        <Amount>0.15</Amount>
        <ItemId>ITM-0000067</ItemId>
        <McsCmBilProductItem class="entity">
            <CgiBundleLines>1</CgiBundleLines>
        </McsCmBilProductItem>
    </McsCmBilCalcInvoiceLine>
    <McsCmBilCalcInvoiceLine class="entity">
        <Amount>0.21</Amount>
        <ItemId>ITM-0000067</ItemId>
        <McsCmBilProductItem class="entity">
            <CgiBundleLines>1</CgiBundleLines>
        </McsCmBilProductItem>
    </McsCmBilCalcInvoiceLine>

    <McsCmBilCalcInvoiceLine class="entity">
        <Amount>96.00</Amount>
        <ItemId>ITM-0000125</ItemId>
        <McsCmBilProductItem class="entity">
            <CgiBundleLines>0</CgiBundleLines>
        </McsCmBilProductItem>
    </McsCmBilCalcInvoiceLine>

    <McsCmBilCalcInvoiceLine class="entity">
        <Amount>-88.00</Amount>
        <ItemId>ITM-0000069</ItemId>
    </McsCmBilCalcInvoiceLine>

    <McsCmBilCalcInvoiceLine class="entity">
        <Amount>-0.66</Amount>
        <ItemId>ITM-0000083</ItemId>
    </McsCmBilCalcInvoiceLine>
    <McsCmBilCalcInvoiceLine class="entity">
        <Amount>-0.22</Amount>
        <ItemId>ITM-0000092</ItemId>
    </McsCmBilCalcInvoiceLine>
    <McsCmBilCalcInvoiceLine class="entity">
        <Amount>-0.55</Amount>
        <ItemId>ITM-0000098</ItemId>
    </McsCmBilCalcInvoiceLine>

</CustInvoiceTable>

และ XSL:

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="Lines-by-ItemId" match="CustInvoiceTable/McsCmBilCalcInvoiceLine" use="CustInvoiceTable/McsCmBilCalcInvoiceLine/ItemId" />

    <xsl:output method="xml" indent="yes" />

    <xsl:template match="/">

        <root>

            <xsl:for-each select="CustInvoiceTable/McsCmBilCalcInvoiceLine[count(. | key('Lines-by-ItemId', ItemId)[1]) = 1][McsCmBilProductItem/CgiBundleLines = 1][not(ItemId = preceding-sibling::McsCmBilCalcInvoiceLine/ItemId)]">
                <xsl:sort select="ItemId" />
                <GroupInvoiceLine>
                    <ItemId><xsl:value-of select="ItemId" /></ItemId>
                    <SumAmount><xsl:value-of select="sum(Amount)"/></SumAmount> <!-- This does not work -->
                </GroupInvoiceLine>
            </xsl:for-each>

        </root>

    </xsl:template>

</xsl:stylesheet>

ผลลัพธ์: สมมติว่าเราจัดกลุ่มที่ "ITM-0000088" ฉันคาดว่าผลลัพธ์จะเป็น 0.12 ขณะนี้เพิ่งคว้าบันทึกแรก

หากเราจัดกลุ่มที่ "ITM-0000083" ฉันคาดว่าผลรวมจะเป็น 6.69 + 7.96 = 14.65 และไม่ใช่ 6.69 + 7.96 + -0.66 = 13.99 ตั้งแต่ 'McsCmBilCalcInvoiceLine' สุดท้ายด้วย 'ItemId = ITM-0000083' ไม่มี 'CgiBundleLines = 1' ใน 'McsCmBilProductItem'


person Lange    schedule 07.03.2016    source แหล่งที่มา
comment
คุณมีรหัสมากมายที่นี่ โปรดโพสต์ตัวอย่างขั้นต่ำ สมบูรณ์ ตรวจสอบได้ (MCVE)   -  person Mark Skelton    schedule 07.03.2016
comment
ใช่ ฉันจะลดปริมาณข้อมูลในครั้งต่อไป ขอบคุณ   -  person Lange    schedule 07.03.2016


คำตอบ (2)


กำหนดคีย์เป็น <xsl:key name="Lines-by-ItemId" match="CustInvoiceTable/McsCmBilCalcInvoiceLine" use="ItemId" /> เนื่องจากค่าแอตทริบิวต์ use ถูกคำนวณโดยสัมพันธ์กับโหนดที่ตรงกัน

จากนั้นหากต้องการดูวิธีใช้คีย์และการจัดกลุ่ม Muenchian ก่อน ให้ใช้

        <xsl:for-each select="CustInvoiceTable/McsCmBilCalcInvoiceLine[count(. | key('Lines-by-ItemId', ItemId)[1]) = 1]">
            <xsl:sort select="ItemId" />
            <GroupInvoiceLine>
                <ItemId><xsl:value-of select="ItemId" /></ItemId>
                <SumAmount><xsl:value-of select="sum(key('Lines-by-ItemId', ItemId)/Amount)"/></SumAmount> 
            </GroupInvoiceLine>
        </xsl:for-each>

สำหรับเงื่อนไขอื่นๆ ให้พิจารณารวมไว้ในรูปแบบคีย์:

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="Lines-by-ItemId" match="CustInvoiceTable/McsCmBilCalcInvoiceLine[McsCmBilProductItem/CgiBundleLines = 1]" use="ItemId" />

    <xsl:output method="xml" indent="yes" />

    <xsl:template match="/">

        <root>

            <xsl:for-each select="CustInvoiceTable/McsCmBilCalcInvoiceLine[McsCmBilProductItem/CgiBundleLines = 1][count(. | key('Lines-by-ItemId', ItemId)[1]) = 1]">
                <xsl:sort select="ItemId" />
                <GroupInvoiceLine>
                    <ItemId><xsl:value-of select="ItemId" /></ItemId>
                    <SumAmount><xsl:value-of select="sum(key('Lines-by-ItemId', ItemId)/Amount)"/></SumAmount> 
                </GroupInvoiceLine>
            </xsl:for-each>

        </root>

    </xsl:template>

</xsl:stylesheet>
person Martin Honnen    schedule 07.03.2016
comment
งานแจ่มอีกแล้ว. ขอบคุณ. - person Lange; 07.03.2016

ขั้นแรก รหัสของคุณควรถูกกำหนดเป็น:

<xsl:key name="Lines-by-ItemId" match="McsCmBilCalcInvoiceLine" use="ItemId" />

จากนั้นเปลี่ยน:

<SumAmount><xsl:value-of select="sum(Amount)"/></SumAmount>

to:

<SumAmount><xsl:value-of select="sum(key('Lines-by-ItemId',ItemId)/Amount)"/></SumAmount>
person michael.hor257k    schedule 07.03.2016
comment
สิ่งนี้ไม่ได้ให้ผลลัพธ์ที่ต้องการ ไม่ได้คำนึงว่าควรจัดกลุ่มเฉพาะบรรทัดที่มี 'CgiBundleLines = 1' เท่านั้น ขอบคุณนะ - person Lange; 07.03.2016
comment
@Lange คุณสามารถเพิ่มเพรดิเคตให้กับกลุ่มที่กำลังสรุปได้ (ไม่ใช่กลยุทธ์ที่ดีที่จะถามมากกว่าหนึ่งสิ่งในเวลาเดียวกัน) - person michael.hor257k; 07.03.2016
comment
ขอบคุณไมเคิล. คุณอาจจะพูดถูก ฉันจะงดเว้นจากสิ่งนี้ในอนาคต - person Lange; 07.03.2016