首页 > 解决方案 > XSLT 1.0 - 如何将 2 个元素/兄弟元素组合成 1 个组

问题描述

我希望我没有严重破坏标题。

我是 XML 和 XSLT 转换的初学者,经过几天的研究和一些严重的试验和错误,我走到了这一步,但现在我绝望了。我似乎无法找到一种方法来组合 customer_ids,因为它们可以来自 2 个不同的元素,并且结果必须具有唯一的 customer_ids。

我应该如何继续这个?

这是源 XML 的示例,我需要转换。

<result>
<row>
    <string>HR-039780</string>
    <string>PER-013</string>
    <null/>
    <string>HelpRequest</string>
    <string>CID-009</string>
    <string>SP-004</string>
    <string>SG-002</string>
</row>
<row>
    <string>SR-003470</string>
    <null/>
    <string>PER-013</string>
    <string>ServiceRequest</string>
    <string>CID-009</string>
    <string>SP-004</string>
    <string>SG-002</string>
</row>
<row>
    <string>SR-009626</string>
    <null/>
    <string>PER-017</string>
    <string>ServiceRequest</string>
    <string>CID-001</string>
    <string>SP-002</string>
    <string>SG-001</string>
</row>
<row>
    <string>HR-035112</string>
    <string>PER-029</string>
    <null/>
    <string>HelpRequest</string>
    <string>CID-015</string>
    <string>SP-002</string>
    <string>SG-001</string>
</row>
<row>
    <string>HR-028904</string>
    <string>PER-024</string>
    <null/>
    <string>HelpRequest</string>
    <string>CID-009</string>
    <string>SP-004</string>
    <string>SG-002</string>
</row>
</result>

这是我正在使用的 XSLT。
通过使用键,我得到了其他独特的值。

<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:key name="support_id" match="*" use="child::*[6]"/>
    <xsl:key name="support_grp_id" match="*" use="child::*[7]"/>
    <xsl:key name="company_id" match="*" use="child::*[5]"/>
    <!-- 
    <xsl:key name="customer_id" match="*" use="**???**"/>
    -->
    
    <xsl:template match="/">
        <data>
        <xsl:for-each select="result/row">
            <xsl:if test="child::*[4] = 'HelpRequest'">
                <work_order>
                    <work_order_id><xsl:value-of select = "child::*[1]"/></work_order_id>
                    <customer_id><xsl:value-of select = "child::*[2]"/></customer_id>
                    <work_type><xsl:value-of select = "child::*[4]"/></work_type>
                    <company_id><xsl:value-of select = "child::*[5]"/></company_id>
                    <support_id><xsl:value-of select = "child::*[6]"/></support_id>
                    <support_grp_id><xsl:value-of select = "child::*[7]"/></support_grp_id>
                </work_order>
            </xsl:if>
            <xsl:if test="child::*[4] = 'ServiceRequest'">
                <work_order>
                    <work_order_id><xsl:value-of select = "child::*[1]"/></work_order_id>
                    <customer_id><xsl:value-of select = "child::*[3]"/></customer_id>
                    <work_type><xsl:value-of select = "child::*[4]"/></work_type>
                    <company_id><xsl:value-of select = "child::*[5]"/></company_id>
                    <support_id><xsl:value-of select = "child::*[6]"/></support_id>
                    <support_grp_id><xsl:value-of select = "child::*[7]"/></support_grp_id>
                </work_order>
            </xsl:if>
        </xsl:for-each>
        <xsl:for-each select="//*[generate-id() = generate-id(key('support_id',child::*[6])[1])]">
            <support>
                <support_id><xsl:value-of select = "child::*[6]"/></support_id>
            </support>
        </xsl:for-each>
        <xsl:for-each select="//*[generate-id() = generate-id(key('support_grp_id',child::*[7])[1])]">
            <support_grp>
                <support_grp_id><xsl:value-of select = "child::*[7]"/></support_grp_id>
            </support_grp>
        </xsl:for-each>
        <xsl:for-each select="//*[generate-id() = generate-id(key('company_id',child::*[5])[1])]">
            <company>
                <company_id><xsl:value-of select = "child::*[5]"/></company_id>
            </company>
        </xsl:for-each>
        <!-- Problem...
        <xsl:for-each select="//*[generate-id() = generate-id(key('customer_id', **???**)[1])]">
            <customer>
                <customer_id><xsl:value-of select = "child::*[ **??? 2 OR 3 ???** ]"/></customer_id>
            </customer>
        </xsl:for-each>
        -->
        </data>
    </xsl:template>
    
</xsl:transform>

结果必须是:

<data>
    <work_order>
        <work_order_id>HR-039780</work_order_id>
        <customer_id>PER-013</customer_id>
        <work_type>HelpRequest</work_type>
        <company_id>CID-009</company_id>
        <support_id>SP-004</support_id>
        <support_grp_id>SG-002</support_grp_id>
    </work_order>
    <work_order>
        <work_order_id>SR-003470</work_order_id>
        <customer_id>PER-013</customer_id>
        <work_type>ServiceRequest</work_type>
        <company_id>CID-009</company_id>
        <support_id>SP-004</support_id>
        <support_grp_id>SG-002</support_grp_id>
    </work_order>
    <work_order>
        <work_order_id>SR-009626</work_order_id>
        <customer_id>PER-017</customer_id>
        <work_type>ServiceRequest</work_type>
        <company_id>CID-001</company_id>
        <support_id>SP-002</support_id>
        <support_grp_id>SG-001</support_grp_id>
    </work_order>
    <work_order>
        <work_order_id>HR-035112</work_order_id>
        <customer_id>PER-029</customer_id>
        <work_type>HelpRequest</work_type>
        <company_id>CID-015</company_id>
        <support_id>SP-002</support_id>
        <support_grp_id>SG-001</support_grp_id>
    </work_order>
    <work_order>
        <work_order_id>HR-028904</work_order_id>
        <customer_id>PER-024</customer_id>
        <work_type>HelpRequest</work_type>
        <company_id>CID-009</company_id>
        <support_id>SP-004</support_id>
        <support_grp_id>SG-002</support_grp_id>
    </work_order>
    <support>
        <support_id>SP-002</support_id>
    </support>
    <support>
        <support_id>SP-004</support_id>
    </support>
    <support_grp>
        <support_grp_id>SG-002</support_grp_id>
    </support_grp>
    <support_grp>
        <support_grp_id>SG-001</support_grp_id>
    </support_grp>
    <company>
        <company_id>CID-001</company_id>
    </company>
    <company>
        <company_id>CID-015</company_id>
    </company>
    <company>
        <company_id>CID-009</company_id>
    </company>
    <customer>
        <customer_id>PER-013</customer_id>
    </customer>
    <customer>
        <customer_id>PER-024</customer_id>
    </customer>
    <customer>
        <customer_id>PER-017</customer_id>
    </customer>
    <customer>
        <customer_id>PER-029</customer_id>
    </customer>
</data>

标签: xmlxslttransformxslt-grouping

解决方案


use="string[2]"<xsl:value-of select = "string[2]"/>如果我没有误解您的输入,那么它应该可以工作。对于所有的键,使用match="row"代替似乎match="*"就足够了,而且效率更高。


推荐阅读