Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old May 30th, 2012, 07:27 AM
Registered User
 
Join Date: May 2012
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default Copy specific node and nodes that used in specific node children

Hello,
i'm new to xslt, just using it for 2weeks not. And now i'm stuck.

So first examples:
Input:
Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <xmi:XMI xmlns:namespace1="http://namespace" xmlns:xmi="http://www.omg.org/spec/XMI/20110701" attribute1="some1" xmlns:M="mOptions" xmlns:N="nOptions">
     
     <namespace1:mode name="Main">
     <node0>0</node0>

    <namespace1:parm name="node1" attribute2="some2" namespace1:type="type1"> 
    	<child1 name="a" id="1"/>
    	<child2 name="b" id="2"/>
    </namespace1:parm>

    <element name="node2" attribute2="some3" namespace1:type="type2"> 
    	<child6 name="a6" id="6"/>
    	<child7 name="b7" id="7"/>
    </element>

    <node id="55"/>

    </namespace1:mode>
 
    <M:extra1 id="1"/>
    <M:extra2 id="2"/>
    <M:extra6 id="6"/>
    <M:extra7 id="7"/>

    </xmi:XMI>
Wanted output:
Code:
    <?xml version="1.0" encoding="UTF-8"?>
<xmi:XMI xmlns:namespace1="http://namespace" xmlns:xmi="http://www.omg.org/spec/XMI/20110701" attribute1="some1" xmlns:M="mOptions" xmlns:N="nOptions">
     
    <namespace1:parm name="node1" attribute2="some2" namespace1:type="type1"> 
        	<child1 name="a" id="1"/>
        	<child2 name="b" id="2"/>
    </namespace1:parm>

    <M:extra1 id="1"/>
    <M:extra2 id="2"/>
</xmi:XMI>
So what i need is to copy a specific node, in this example name=node1 and namespace1:type=type1, then remove all <M:extra.../> nodes that are not used in specific node. It can be that node will be name="node2" and namespace1:type=type2, but node name should become namespace1:parm.
Name will differ, but figure out that i can read the name from options file into a variable.

For now i'm trying to clean up the xmi using:
Code:
<xsl:template match="xmi:XMI|*[@namespace1:type='type1']">
        <xsl:copy>
            <xsl:for-each select="@*">
                <xsl:attribute name="{name(.)}">
                    <xsl:value-of select="."/>
                </xsl:attribute>
            </xsl:for-each>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
but getting:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<xmi:XMI xmlns:namespace1="http://namespace"
         xmlns:xmi="http://www.omg.org/spec/XMI/20110701"
         xmlns:M="mOptions"
         xmlns:N="nOptions"
         attribute1="some1">0<namespace1:parm name="node1" attribute2="some2" namespace1:type="type1"/>
</xmi:XMI>
somehow i get 0 and do not get children of wanted node. Have no clue how to clean up/keep some <M:extra.../> tags yet.

When i try
Code:
<xsl:template match="*">
        <xsl:copy>
            <xsl:for-each select="@*">
                <xsl:attribute name="{name(.)}">
                    <xsl:value-of select="."/>
                </xsl:attribute>
            </xsl:for-each>
            <xsl:apply-templates select="xmi:XMI|*[@namespace1:type='type1']"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="xmi:XMI|*[@namespace1:type='type1']">
        <xsl:copy>
            <xsl:for-each select="@*">
                <xsl:attribute name="{name(.)}">
                    <xsl:value-of select="."/>
                </xsl:attribute>
            </xsl:for-each>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
im getting:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<xmi:XMI xmlns:namespace1="http://namespace"
         xmlns:xmi="http://www.omg.org/spec/XMI/20110701"
         xmlns:M="mOptions"
         xmlns:N="nOptions"
         attribute1="some1">some1<namespace1:mode name="Main">
      <namespace1:parm name="node1" attribute2="some2" namespace1:type="type1">node1some2type1<child1 name="a" id="1"/>
         <child2 name="b" id="2"/>
      </namespace1:parm>
   </namespace1:mode>
   <M:extra1 id="1"/>
   <M:extra2 id="3"/>
   <M:extra6 id="6"/>
   <M:extra7 id="7"/>
</xmi:XMI>
Somehow i'm getting node1some2type1 in between my specific node and some1<namespace1:mode name="Main"> and children and still do not have a clue how to remove <M:extra...> thinking maybe can be done with another template mapping used children or something.

Last edited by TerTer; May 30th, 2012 at 08:36 AM..
 
Old May 30th, 2012, 10:37 AM
Registered User
 
Join Date: May 2012
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default

After few tries got this
Code:
<xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="namespace1:mode">
        <xsl:call-template name="RecursiveCopy"/>
    </xsl:template>

    <xsl:template name="RecursiveCopy">
        <xsl:for-each select="*">
            <xsl:if test="attribute()=$type">
                <xsl:element name="namespace1:parm">
                     <xsl:apply-templates select="@*|node()"/>
                </xsl:element>
            </xsl:if>
            <xsl:if test="not(attribute()=$type)">
                <xsl:call-template name="RecursiveCopy"/>
            </xsl:if>
        </xsl:for-each>
    </xsl:template>
After applying it i get this:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<xmi:XMI xmlns:namespace1="http://namespace"
         xmlns:xmi="http://www.omg.org/spec/XMI/20110701"
         xmlns:M="mOptions"
         xmlns:N="nOptions"
         attribute1="some1">
   <namespace1:parm name="node2" attribute2="some3" namespace1:type="type2">
      <child6 name="a6" id="6"/>
      <child7 name="b7" id="7"/>
   </namespace1:parm>
   <M:extra1 id="1"/>
   <M:extra2 id="3"/>
   <M:extra6 id="6"/>
   <M:extra7 id="7"/>
</xmi:XMI>
now i need to remove <M:extra../> tags that are not used in so need to remove <M:extra1 id="1"/> and <M:extra2 id="3"/> as id 6-7 is used in namespace1:parm.

Also i still need if there is only namespace1:parm and xmi:XMI left to merge xmi:XMI with my tag copying all namespaces and attributes.
Code:
..
<xmi:XMI namespace2 attribute2>
<namespace1:parm attribute1 namespace1>
...
</namespace1:parm>
</xmi:XMI
need to get
Code:
..
<namespace1:parm namespace1 attribute1 namespace2 attribute2>
...
</namespace1:parm>





Similar Threads
Thread Thread Starter Forum Replies Last Post
XSLT Escape specific Node Marzipan XSLT 1 March 23rd, 2012 02:13 PM
Copying all the nodes except the specific node arunprasadlv XSLT 14 July 22nd, 2009 09:19 AM
Not outputting a specific node zach_1988 XSLT 3 December 2nd, 2008 10:49 AM
Introducing parent node to specific siblings Frimann XSLT 11 July 3rd, 2008 03:20 PM
Copy parent node and not its children bonekrusher XSLT 4 August 29th, 2007 08:44 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.