Need help in XSLT Code for the forming child nodes

2019-08-16 13:18发布

问题:

I am facing difficult while forming child 3 and child 4 elements like the below expected output, but no luck.

Input Message coming from external source:

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <PurchaseOrder id="aoi00037607">
        <attr attr-name="A">
            <new-value>adi00010210</new-value>
        </attr>
        <attr attr-name="B">
            <new-value>99</new-value>
        </attr>
        <attr attr-name="C">
            <new-value>active</new-value>
        </attr>
        <attr attr-name="D">
            <new-value>
                <child1>iop00010538</child1>
                <child2>2</child2>
            </new-value>
            <new-value>
                <child1>cid2313213</child1>
                <child2>2</child2>
            </new-value>
            <new-value>
                <child1>hri00075562</child1>
                <child2>1</child2>
            </new-value>
        </attr>
        <attr attr-name="E">
            <new-value>
                <materials type="required">
                    <material system="XXX">
                        <attr attr-name="child3">primary</attr>
                        <attr attr-name="child4">2</attr>
                    </material >
                </materials>
            </new-value>
        </attr>
</PurchaseOrder>

XSLT Code written to transform

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="urn:demo:PurchaseOrder">
    <xsl:output method="xml" indent="yes" />
    <xsl:strip-space elements="*" />
    <xsl:key name="keyAttrName" match="attr" use="@attr-name" />
    <xsl:template match="PurchaseOrder">
        <ns0:PurchaseOrderMSG>>
            <Orders>
                <Order id="{@id}">
                    <xsl:for-each select="attr[generate-id() = generate-id(key('keyAttrName', @attr-name)[1])]">
                        <xsl:variable name="nodeName" select="@attr-name" />
                        <xsl:choose>
                            <xsl:when test="key('keyAttrName', @attr-name)/new-value/*/node()">
                                <xsl:for-each select="new-value">
                                    <xsl:element name="{$nodeName}">
                                        <xsl:copy-of select="*" />
                                    </xsl:element>
                                </xsl:for-each>
                            </xsl:when>
                            <xsl:when test="key('keyAttrName', @attr-name)/new-value/materials/material">
                                <xsl:for-each select="key('keyAttrName', @attr-name)">
                                    <xsl:element name="{$nodeName}">
                                        <xsl:copy-of select="attr" />
                                    </xsl:element>
                                </xsl:for-each>
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:for-each select="key('keyAttrName', @attr-name)">
                                    <xsl:element name="{$nodeName}">
                                        <xsl:value-of select="new-value" />
                                    </xsl:element>
                                </xsl:for-each>
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:for-each>
                </Order>
            </Orders>
        </ns0:PurchaseOrderMSG>
    </xsl:template>
</xsl:stylesheet>

The below code in the above xslt is not giving any result

                    <xsl:when test="key('keyAttrName', @attr-name)/new-value/materials/material">
                        <xsl:for-each select="key('keyAttrName', @attr-name)">
                            <xsl:element name="{$nodeName}">
                                <xsl:copy-of select="attr" />
                            </xsl:element>
                        </xsl:for-each>
                    </xsl:when>

Expected Result:

<?xml version="1.0" encoding="UTF-8"?>
<ns0:PurchaseOrderMSG xmlns:ns0="urn:demo:PurchaseOrder">
    <Orders>
        <Order>
            <A>adi00010210</A>
            <B>99</B>
            <C>active </C>
            <D>
                <Child1>iop00010538</Child1>
                <Child2>2</Child2>
            </D>
            <D>
                <child1>cid2313213</child1>
                <child2>2</child2>
            </D>
            <D>
                <child1>hri00075562</child1>
                <child2>1</child2>
            </D>
            <E>
                <Materials type="required">
                    <Material system="XXXX">
                        <child3>primary</child3>
                        <child4>2</child4>
                    </Material>
                </Materials>
            </E>
        </Order>
    </Orders>
</ns0:PurchaseOrderMSG>

What needs to be corrected to get the expected result?

Link for reference: Need help in forming target xml using XSLT

回答1:

Change

<xsl:when test="key('keyAttrName', @attr-name)/new-value/*/node()">

to

<xsl:when test="key('keyAttrName', @attr-name)/new-value/*/node()[not(name() = 'material')]">

because of this terminate conditions and your specified script not process.



标签: xslt