Merge different products belong to each standard

2020-04-20 21:32发布

I have to transform the following xml content,

<Standards xmlns="http://ws.wso2.org/dataservice">
    <Standard>
        <ProductID>200057</ProductID>
        <Prefix>ISO</Prefix>
        <SNumber>1001</SNumber>
        <DraftProducts>
            <RelatedProduct>
                <ProductID>1500163</ProductID>
            </RelatedProduct>
        </DraftProducts>
        <ReferenceProducts>
            <RelatedProduct>
                <ProductID>263973</ProductID>
                <RelationId>708519</RelationId>
                <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            </RelatedProduct>
            <RelatedProduct>
                <ProductID>320056</ProductID>
                <RelationId>934789</RelationId>
                <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            </RelatedProduct>
        </ReferenceProducts>
        <RelatedIntProducts>
            <RelatedProduct>
                <ProductID xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
                <RelationId>116881</RelationId>
                <Relationship>Identical</Relationship>
                <Designation>NEN ISO 1001</Designation>
            </RelatedProduct>
            <RelatedProduct>
                <ProductID>208076</ProductID>
                <RelationId>116886</RelationId>
                <Relationship>Identical</Relationship>
                <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            </RelatedProduct>
        </RelatedIntProducts>
        <S1>1001</S1>
        <S2>1986</S2>
    </Standard>
    <Standard>
        <ProductID>200058</ProductID>
        <Prefix>ISO</Prefix>
        <SNumber>1002</SNumber>
        <DraftProducts>
            <RelatedProduct>
                <ProductID>1500167</ProductID>
            </RelatedProduct>
        </DraftProducts>
        <ReferenceProducts>
            <RelatedProduct>
                <ProductID>263974</ProductID>
                <RelationId>708519</RelationId>
                <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            </RelatedProduct>
            <RelatedProduct>
                <ProductID>320052</ProductID>
                <RelationId>934754</RelationId>
                <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            </RelatedProduct>
        </ReferenceProducts>
        <RelatedIntProducts>
            <RelatedProduct>
                <ProductID xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
                <RelationId>116837</RelationId>
                <Relationship>Identical</Relationship>
                <Designation>NEN ISO 1001</Designation>
            </RelatedProduct>
            <RelatedProduct>
                <ProductID>208074</ProductID>
                <RelationId>116843</RelationId>
                <Relationship>Identical</Relationship>
                <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            </RelatedProduct>
        </RelatedIntProducts>
        <S1>1005</S1>
        <S2>1983</S2>
    </Standard>
</Standards>

in to this output format,

<Standards xmlns="http://ws.wso2.org/dataservice">
    <Standard>
        <ProductID>200057</ProductID>
        <Prefix>ISO</Prefix>
        <SNumber>1001</SNumber>
        <RelatedProducts>
            <RelatedProduct>
                <ProductID>1500163</ProductID>
                <RelationType>DraftProducts</RelationType>
            </RelatedProduct>
            <RelatedProduct>
                <ProductID>263973</ProductID>
                <RelationId>708519</RelationId>
                <RelationType>ReferenceProducts</RelationType>
                <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            </RelatedProduct>
            <RelatedProduct>
                <ProductID>320056</ProductID>
                <RelationId>934789</RelationId>
                <RelationType>ReferenceProducts</RelationType>
                <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            </RelatedProduct>
            <RelatedProduct>
                <ProductID xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
                <RelationId>116881</RelationId>
                <Relationship>Identical</Relationship>
                <RelationType>RelatedIntProducts</RelationType>
                <Designation>NEN ISO 1001</Designation>
            </RelatedProduct>
            <RelatedProduct>
                <ProductID>208076</ProductID>
                <RelationId>116886</RelationId>
                <RelationType>RelatedIntProducts</RelationType>
                <Relationship>Identical</Relationship>
                <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            </RelatedProduct>
        </RelatedProducts>
        <S1>1001</S1>
        <S2>1986</S2>
    </Standard>
    <Standard>
        <ProductID>200058</ProductID>
        <Prefix>ISO</Prefix>
        <SNumber>1002</SNumber>
        <RelatedProducts>
            <RelatedProduct>
                <ProductID>1500167</ProductID>
                <RelationType>DraftProducts</RelationType>
            </RelatedProduct>
            <RelatedProduct>
                <ProductID>263974</ProductID>
                <RelationId>708519</RelationId>
                <RelationType>ReferenceProducts</RelationType>
                <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            </RelatedProduct>
            <RelatedProduct>
                <ProductID>320052</ProductID>
                <RelationId>934754</RelationId>
                <RelationType>ReferenceProducts</RelationType>
                <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            </RelatedProduct>
            <RelatedProduct>
                <ProductID xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
                <RelationId>116837</RelationId>
                <RelationType>RelatedIntProducts</RelationType>
                <Relationship>Identical</Relationship>
                <Designation>NEN ISO 1001</Designation>
            </RelatedProduct>
            <RelatedProduct>
                <ProductID>208074</ProductID>
                <RelationId>116843</RelationId>
                <RelationType>RelatedIntProducts</RelationType>
                <Relationship>Identical</Relationship>
                <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            </RelatedProduct>
        </RelatedProducts>
        <S1>1005</S1>
        <S2>1983</S2>
    </Standard>
</Standards>

I have used following xslt, but still does not give the output as expected. The given xslt works only when there's one standard. But with multiple standards it gives duplicated results due to the xsl template which I used here.

<?xml version="1.0" encoding="UTF-8"?>

<!-- When matching RelatedIntProducts: do nothing -->
<xsl:template match="//x:Standards/x:Standard/x:DraftProducts" />
<xsl:template match="//x:Standards/x:Standard/x:RelatedIntProducts" />
<xsl:template match="//x:Standards/x:Standard/x:SupersdProducts" />
<xsl:template match="//x:Standards/x:Standard/x:LinkProducts" />


    <xsl:template match="//x:Standards/x:Standard/x:ReferenceProducts">
        <RelatedProducts>
            <xsl:for-each select="//x:Standards/x:Standard/*/x:RelatedProduct">
                <RelatedProduct>
                    <ProductID>
                        <xsl:value-of select="x:ProductID">
                        </xsl:value-of>
                    </ProductID>
                    <RelationId>
                        <xsl:value-of select="x:RelationId">
                        </xsl:value-of>
                    </RelationId>

                    <RelationType>
                        <xsl:value-of select="name(..)" />
                    </RelationType>
                </RelatedProduct>
            </xsl:for-each>
        </RelatedProducts>
    </xsl:template>

</xsl:stylesheet>

For each standard I need to merge all the different types of RelatedProducts into one list named RelatedProducts. Also I need to keep the other stuffs as it is. Could you please help me to achieve this.

1条回答
ゆ 、 Hurt°
2楼-- · 2020-04-20 22:08

Switching from imperative "pull" processing (<xsl:for-each...>) to "push" processing, where you depend on the natural processing loop of the XSL engine, simplifies the stylesheet significantly.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:x="http://ws.wso2.org/dataservice"
    xmlns="http://ws.wso2.org/dataservice"
    exclude-result-prefixes="x"
    version="1.0">

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

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

    <xsl:template match="x:Standard">
        <xsl:copy>
            <xsl:copy-of select="x:ProductID"/>
            <xsl:copy-of select="x:Prefix"/>
            <xsl:copy-of select="x:SNumber"/>
            <RelatedProducts>
                <xsl:apply-templates select=".//x:RelatedProduct"/>
            </RelatedProducts>
            <xsl:copy-of select="x:S1"/>
            <xsl:copy-of select="x:S2"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="x:RelatedProduct">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
            <RelationType><xsl:value-of select="name(..)"/></RelationType>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

This is essentially an "identity transform" plus one template to match Standard, and output only what we want from within it. The template for x:RelatedProduct copies those elements to the output verbatim and adds the RelationType element whose text is the name of the containing element.

Output is

<?xml version="1.0" encoding="UTF-8"?>
<Standards xmlns="http://ws.wso2.org/dataservice">
    <Standard>
      <ProductID>200057</ProductID>
      <Prefix>ISO</Prefix>
      <SNumber>1001</SNumber>
      <RelatedProducts>
         <RelatedProduct>
                <ProductID>1500163</ProductID>
            <RelationType>DraftProducts</RelationType>
         </RelatedProduct>
         <RelatedProduct>
                <ProductID>263973</ProductID>
                <RelationId>708519</RelationId>
                <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            <RelationType>ReferenceProducts</RelationType>
         </RelatedProduct>
         <RelatedProduct>
                <ProductID>320056</ProductID>
                <RelationId>934789</RelationId>
                <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            <RelationType>ReferenceProducts</RelationType>
         </RelatedProduct>
         <RelatedProduct>
                <ProductID xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
                <RelationId>116881</RelationId>
                <Relationship>Identical</Relationship>
                <Designation>NEN ISO 1001</Designation>
            <RelationType>RelatedIntProducts</RelationType>
         </RelatedProduct>
         <RelatedProduct>
                <ProductID>208076</ProductID>
                <RelationId>116886</RelationId>
                <Relationship>Identical</Relationship>
                <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            <RelationType>RelatedIntProducts</RelationType>
         </RelatedProduct>
      </RelatedProducts>
      <S1>1001</S1>
      <S2>1986</S2>
   </Standard>
    <Standard>
      <ProductID>200058</ProductID>
      <Prefix>ISO</Prefix>
      <SNumber>1002</SNumber>
      <RelatedProducts>
         <RelatedProduct>
                <ProductID>1500167</ProductID>
            <RelationType>DraftProducts</RelationType>
         </RelatedProduct>
         <RelatedProduct>
                <ProductID>263974</ProductID>
                <RelationId>708519</RelationId>
                <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            <RelationType>ReferenceProducts</RelationType>
         </RelatedProduct>
         <RelatedProduct>
                <ProductID>320052</ProductID>
                <RelationId>934754</RelationId>
                <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            <RelationType>ReferenceProducts</RelationType>
         </RelatedProduct>
         <RelatedProduct>
                <ProductID xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
                <RelationId>116837</RelationId>
                <Relationship>Identical</Relationship>
                <Designation>NEN ISO 1001</Designation>
            <RelationType>RelatedIntProducts</RelationType>
         </RelatedProduct>
         <RelatedProduct>
                <ProductID>208074</ProductID>
                <RelationId>116843</RelationId>
                <Relationship>Identical</Relationship>
                <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            <RelationType>RelatedIntProducts</RelationType>
         </RelatedProduct>
      </RelatedProducts>
      <S1>1005</S1>
      <S2>1983</S2>
   </Standard>
</Standards>
查看更多
登录 后发表回答