XSLT 1.0 中的匹配和合并 [英] Match and Merge in XSLT 1.0

查看:21
本文介绍了XSLT 1.0 中的匹配和合并的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含多个父节点的示例 XML 消息.要求类似于如果两个父节点相同,则合并子节点.

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.

示例输入消息是

<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>

我们需要连接所有行的 temperatureCode 的值、所有的温度值(如果存在),如果它们是重复的,则合并父级中 child 的 temperatureStats 内的行.

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.

推荐答案

我认为您在之前的答案中找到了一个可以分组的解决方案 https://stackoverflow.com/a/38240246/252228,然后就可以调用key函数处理分组中的item:

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.

这篇关于XSLT 1.0 中的匹配和合并的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆