Match and Merge in XSLT 1.0

回眸只為那壹抹淺笑 提交于 2019-12-13 21:32:57

问题


I have a sample XML message which contains multiple parent node. The requirement is something like if the two parent node are same, merge the child node.

Sample Input Message is

<document>
<party>
    <gtin>1000909090</gtin>
    <pos>
        <attrGroupMany name="temperatureInformation">
            <row>
                <attr name="temperatureCode">STORAGE</attr>
                <attrQualMany name="temperature">
                    <value qual="FAH">10</value>
                    <value qual="CC">20</value>
                </attrQualMany>
                <attrGroupMany name="temperatureStats">
                    <row>
                        <attr name="StatsCode">CODE1</attr>
                    </row>
                    <row>
                        <attr name="StatsCode">CODE2</attr>
                    </row>
                </attrGroupMany>
            </row>
            <row>
                <attr name="temperatureCode">STORAGE</attr>
                <attrQualMany name="temperature">
                    <value qual="FAH">10</value>
                    <value qual="CC">20</value>
                </attrQualMany>
                <attrGroupMany name="temperatureStats">
                    <row>
                        <attr name="StatsCode">CODE3</attr>
                    </row>
                    <row>
                        <attr name="StatsCode">CODE4</attr>
                    </row>
                </attrGroupMany>
            </row>
            <row>
                <attr name="temperatureCode">HANDLING</attr>
                <attrQualMany name="temperature">
                    <value qual="FAH">10</value>                    
                </attrQualMany>
                <attrGroupMany name="temperatureStats">
                    <row>
                        <attr name="StatsCode">CODE5</attr>
                    </row>
                    <row>
                        <attr name="StatsCode">CODE6</attr>
                    </row>
                </attrGroupMany>
            </row>
            <row>
                <attr name="temperatureCode">HANDLING</attr>
                <attrGroupMany name="temperatureStats">
                    <row>
                        <attr name="StatsCode">CODE7</attr>
                    </row>
                    <row>
                        <attr name="StatsCode">CODE8</attr>
                    </row>
                </attrGroupMany>
            </row>
        </attrGroupMany>
    </pos>
</party>
</document>

we need to concat the value of temperatureCode, All value of temperature (if present) for all row and if they are duplicate, then merge the row inside temperatureStats of the child in the parent.

Expected output is in the same structure. You can see the second node is merged with first

<document>
<party>
    <gtin>1000909090</gtin>
    <pos>
        <attrGroupMany name="temperatureInformation">
            <row>
                <attr name="temperatureCode">STORAGE</attr>
                <attrQualMany name="temperature">
                    <value qual="FAH">10</value>
                    <value qual="CC">20</value>
                </attrQualMany>
                <attrGroupMany name="temperatureStats">
                    <row>
                        <attr name="StatsCode">CODE1</attr>
                    </row>
                    <row>
                        <attr name="StatsCode">CODE2</attr>
                    </row>
                    <row>
                        <attr name="StatsCode">CODE3</attr>
                    </row>
                    <row>
                        <attr name="StatsCode">CODE4</attr>
                    </row>
                </attrGroupMany>
            </row>
            <row>
                <attr name="temperatureCode">HANDLING</attr>
                <attrQualMany name="temperature">
                    <value qual="FAH">10</value>                    
                </attrQualMany>
                <attrGroupMany name="temperatureStats">
                    <row>
                        <attr name="StatsCode">CODE5</attr>
                    </row>
                    <row>
                        <attr name="StatsCode">CODE6</attr>
                    </row>
                </attrGroupMany>
            </row>
            <row>
                <attr name="temperatureCode">HANDLING</attr>
                <attrGroupMany name="temperatureStats">
                    <row>
                        <attr name="StatsCode">CODE7</attr>
                    </row>
                    <row>
                        <attr name="StatsCode">CODE8</attr>
                    </row>
                </attrGroupMany>
            </row>
        </attrGroupMany>
    </pos>
</party>
</document>

Any input will be very valuable.


回答1:


I think you got a solution to group in a previous answer https://stackoverflow.com/a/38240246/252228, you can then process the items in a group calling the key function:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

    <xsl:output indent="yes"/>


    <xsl:key name="group" match="attrGroupMany[@name = 'temperatureInformation']/row"
        use="concat(attr[@name = 'temperatureCode'], '|', attrQualMany[@name = 'temperature'])"/>

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="attrGroupMany[@name = 'temperatureInformation']">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:apply-templates select="row[generate-id() = generate-id(key('group', concat(attr[@name = 'temperatureCode'], '|', attrQualMany[@name = 'temperature']))[1])]"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="attrGroupMany[@name = 'temperatureStats']">
        <xsl:copy>
            <xsl:apply-templates select="@* | key('group', concat(../attr[@name = 'temperatureCode'], '|', ../attrQualMany[@name = 'temperature']))/attrGroupMany[@name = 'temperatureStats']/row"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

Note however that the whole approach of taking the string value of an element with varying child elements is brittle, if there is a difference in white space the value might be considered different.



来源:https://stackoverflow.com/questions/38264397/match-and-merge-in-xslt-1-0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!