1

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

1 Answer 1

1

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>
Sign up to request clarification or add additional context in comments.

5 Comments

thanks ... It worked. Can u suggest any link or book to enhance my skill in XSLT. I am just a begginer in this.
i have slightly changed my output... can you please help what changes it will be required to get the output..
I've amended my answer this time, but bear in mind for the future, that it is considered bad practise to amend a question after the answer has been accepted. Thank you.
Thanks .. I'll keep this thing in mind. Thanks once again

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.