简体   繁体   中英

Grouping XML attribute with XSLT

Input XML :

 <?xml version="1.0" encoding="UTF-8"?><svg height="3553.21" width="9358.09" viewBox="0 0 9358.09 3553.21" xmlns="http://www.w3.org/2000/svg"> <rect fill="#16202c" x="0" y="0" width="9358.09" height="3553.21"/> <g transform="scale(0.7)> <g id="0-0-0" class="classPolyline" type="twycenterline" nameObject="WW12" sizeMin="" sizeMax=""> <polyline fill="none" stroke="#292929" stroke-width="0.2" fill-opacity="1" points="218.36444444444453,127.61111111111109 "/> </g> <g id="1-0-0" class="classPolyline" type="twycenterline" nameObject="WW12" sizeMin="" sizeMax=""> <polyline fill="none" stroke="#292929" stroke-width="0.2" fill-opacity="1" points="462.22222222222223,127.14222222222219 "/> </g> <g id="2-0-0" class="classPolyline" type="twy" nameObject="WW12" sizeMin="" sizeMax=""> <polyline fill="none" stroke="#292929" stroke-width="0.2" fill-opacity="1" points="462.22222222222223,127.14222222222219 "/> </g> <g id="3-0-0" class="classPolyline" type="circle" nameObject="WW12" sizeMin="" sizeMax=""> <text class="classText" id="12200-0-0" type="lamp_label_only" fill="#ffffff">20L-AP2-065A</text> </g> <g id="4-0-0" class="classPolyline" type="circle" nameObject="WW12" sizeMin="" sizeMax=""> <text class="classText" id="12201-0-0" type="lamp_label_only" fill="#ffffff">WW8c-008B</text> </g> </g> </svg>

Expected Output:

 <?xml version="1.0" encoding="UTF-8"?><svg height="3553.21" width="9358.09" viewBox="0 0 9358.09 3553.21" xmlns="http://www.w3.org/2000/svg"> <rect fill="#16202c" x="0" y="0" width="9358.09" height="3553.21"/> <g transform="scale(0.7)> <g type="twycenterline"> <g id="0-0-0" class="classPolyline" type="twycenterline" nameObject="WW12" sizeMin="" sizeMax=""> <polyline fill="none" stroke="#292929" stroke-width="0.2" fill-opacity="1" points="218.36444444444453,127.61111111111109 "/> </g> <g id="1-0-0" class="classPolyline" type="twycenterline" nameObject="WW12" sizeMin="" sizeMax=""> <polyline fill="none" stroke="#292929" stroke-width="0.2" fill-opacity="1" points="462.22222222222223,127.14222222222219 "/> </g> </g> <g type="twy"> <g id="2-0-0" class="classPolyline" type="twy" nameObject="WW12" sizeMin="" sizeMax=""> <polyline fill="none" stroke="#292929" stroke-width="0.2" fill-opacity="1" points="462.22222222222223,127.14222222222219 "/> </g> </g> <g type="circle"> <g id="3-0-0" class="classPolyline" type="circle" nameObject="WW12" sizeMin="" sizeMax=""> <text class="classText" id="12200-0-0" type="lamp_label_only" fill="#ffffff">20L-AP2-065A</text> </g> <g id="4-0-0" class="classPolyline" type="circle" nameObject="WW12" sizeMin="" sizeMax=""> <text class="classText" id="12201-0-0" type="lamp_label_only" fill="#ffffff">WW8c-008B</text> </g> </g> </g> </svg>

My XSLT file that i have worked on. Not sure what is going wrong on this

<?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" method="xml" />

    <xsl:key name="type1" match="g" use="@type" />

    <xsl:template match="/">
        <svg  xmlns="http://www.w3.org/2000/svg" >
            <xsl:variable name="viewWidth"><xsl:value-of select=".//@width"/></xsl:variable>
            <xsl:variable name="viewHeight"><xsl:value-of select=".//@height"/></xsl:variable>

            <xsl:attribute name="height"><xsl:value-of select="$viewHeight" /></xsl:attribute>
            <xsl:attribute name="width"><xsl:value-of select="$viewWidth" /></xsl:attribute>

            <g>
                <xsl:variable name="trans"><xsl:value-of select=".//@transform"/></xsl:variable>
                <xsl:attribute name="transform"><xsl:value-of select="$trans" /></xsl:attribute>

                <xsl:variable name="type"><xsl:value-of select=".//@type"/></xsl:variable>

                <xsl:comment>trans <xsl:copy-of select="$trans" /></xsl:comment>
                <xsl:comment>type <xsl:copy-of select="$type" /></xsl:comment>


                <xsl:apply-templates select="g[generate-id(.)=generate-id(key('type1',@type)[1])]"/>
            </g>
        </svg>
    </xsl:template>

    <xsl:template match="g">
        <xsl:comment>template <xsl:copy-of select="template" /></xsl:comment>
        <g value="{@type}">
            <xsl:comment>g1111 <xsl:copy-of select="g11111" /></xsl:comment>
            <xsl:for-each select="key('type1', @type)">
                <xsl:comment><xsl:copy-of select="@type" /></xsl:comment>

            </xsl:for-each>
        </g>

    </xsl:template>


</xsl:stylesheet>

I have read many blogs on this but not i am not able to create group. Below are the details . Input XML thats need to be transformed into the expected output. Below i have shared both input and output XMl and my XSLT file. Any Help please....

You have two problems with your XSLT

  1. Your initial template matches "/" which is the document node. However, when you do xsl:apply-templates you select "g" which is not a child of the document node ("svg" is the child of the document node). To get around this, you can change your template match to "/*" instead.

  2. You have not accounted for namespaces in your XSLT. All elements in your XML are in the " http://www.w3.org/2000/svg " namespace, but in your XSLT you are looking for elements in no namespace. To get around this, you need to declare the namespace (with a prefix) in the XSLT, and then use that prefix when matching any element.

It may also help if you use the identity template in your XSLT, to help with copying existing elements, as this will help simplify your XSLT a lot.

Try this XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
                xmlns:svg="http://www.w3.org/2000/svg">
    <xsl:output indent="yes" method="xml" />

    <xsl:key name="type1" match="svg:g[@type]" use="@type" />

    <!-- Matches the first distinct 'type' attribute -->
    <xsl:template match="svg:g[@transform]">
        <xsl:copy>
            <xsl:apply-templates select="@*" />
            <xsl:for-each select="svg:g[generate-id()=generate-id(key('type1',@type)[1])]">
                <xsl:copy>
                    <xsl:attribute name="type">
                        <xsl:value-of select="@type" />
                    </xsl:attribute>
                    <xsl:apply-templates select="key('type1', @type)" />
                </xsl:copy>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM