Solved

How to Rename an XmlNode and all its Children

Posted on 2003-11-21
4
6,236 Views
Last Modified: 2007-12-19
I'm trying to figure out the best way to rename an element and all of its children. For example, I would like to prepend or append arbitrary text to distinguish the node (and its children) for use in a DataSet. The code below is in .NET. The place I'm having a problem is noted below. Is there a better way to do this, XSLT perhaps?

BTW: I have to do this in C# .NET, so DOM3 isn't an option.

private void ProcessChildren(XmlNode xnod, int Depth)
{
   if ((xnod.NodeType == XmlNodeType.Element))
   {
       // WHAT DO I DO HERE TO RENAME THE CURRENT NODE???

       // Process the children of this node
       XmlNode xnodworking;
       if (xnod.HasChildNodes)
       {
            xnodworking = xnod.FirstChild;
            while(xnodworking != null)
            {
                  ProcessChildren(xnodworking, Depth + 1);
                  xnodworking = xnodworking.NextSibling;
            }
        }
    }
}

private XmlNode RenameNodes(System.Xml.XmlNode rs_node)
{
    XmlNode xnodWorking;
    if (rs_node.HasChildNodes)
    {
        xnodWorking = rs_node.FirstChild;
        while(xnodWorking != null)
        {
            ProcessChildren(xnodWorking, 0);
            xnodWorking = xnodWorking.NextSibling;
        }
     }
     return null;
}

Thanks.
0
Comment
Question by:brian_dallas
4 Comments
 
LVL 15

Accepted Solution

by:
dualsoul earned 250 total points
ID: 9803955
> Is there a better way to do this, XSLT perhaps
i'm not working with .NET now, so i show you how to use XSLT for your task, and you decide what's better for you: XSLT or hand coded DOM manipulations

so...for instance you have xml, like that:
     <news>
           <title>some title</title>
           <author>some name</author>
           <message>some message</message>
       </news>
and want to rename:
     news -> NEWS
     title   -> TITLE
     author -> AUTHOR
      message -> MESSAGE

your XSLT will be:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
            <xsl:for-each select="news">
                      <NEWS>
                           <xsl:for-each select="title">                      
                              <TITLE>
                                    <xsl:value-of select="."/>
                               </TITLE>
                            </xsl:for-each>    

                           <xsl:for-each select="author">                      
                              <AUTHOR>
                                    <xsl:value-of select="."/>
                               </AUTHOR>
                            </xsl:for-each>    

                           <xsl:for-each select="message">                      
                              <MESSAGE>
                                    <xsl:value-of select="."/>
                               </MESSAGE>
                            </xsl:for-each>    

                      </NEWS>
             </xsl:for-each>
     </xsl:template>
</xsl:stylesheet>
         

certanly you can write common XSLT, which will not use particular node-names, and will rename all nodes, using some rule, for instance add a prefix for all names.

Hope it helps.
0
 
LVL 9

Assisted Solution

by:sparkplug
sparkplug earned 250 total points
ID: 9809522
Hi,

There is no renameNode() method in the XML DOM. The only way to rename nodes using the DOM is to create a new node with the new name, copy all the child nodes and attributes from the old node to the new node, then replace the old node with the new node. Below is an example of how to do this using javascript. It should not be too difficult to translate this to C#.

sXML='<root><OldName id="2"><node2 id="3">test</node2></OldName></root>';

// load DOM
oXMLDom = new ActiveXObject("MSXML2.DOMDocument.4.0");
oXMLDom.async = false;
oXMLDom.loadXML(sXML);

//select old node
oOldNode = oXMLDom.selectSingleNode("//OldName");

//create new node
oNewNode = oXMLDom.createElement("NewName");

///copy attributes
for (i=0; i< oOldNode.attributes.length; i++)
{
      oNewNode.setAttributeNode(oOldNode.attributes[i].cloneNode(true));
}

//copy child nodes
for (i=0; i< oOldNode.childNodes.length; i++)
{
      oChildNode = oOldNode.childNodes[i].cloneNode(true);
      oNewNode.appendChild(oChildNode);
}


//replace nodes
oOldNode.parentNode.replaceChild(oNewNode, oOldNode);


alert(oXMLDom.xml);


XSLT may be a better approach as it is more flexible in that you can easily rename all ocurrences of a particular node. The following XSLT renames any nodes called "OldName" to "NewName" and renames the node "/Root/Node/OldName2" to "NewName2". This example also ensures that all the child nodes and attributes are retained.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

<!-- rename all nodes called OldName -->
<xsl:template match="OldName">
     <NewName>
           <xsl:apply-templates/>
     </NewName>
</xsl:template>

<!-- rename a specific node -->
<xsl:template match="/Root/Node/OldName2">
     <NewName2>
           <xsl:apply-templates/>
     </NewName2>
</xsl:template>


</xsl:stylesheet>


>S'Plug<





0

Featured Post

3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

The Client Need Led Us to RSS I recently had an investment company ask me how they might notify their constituents about their newsworthy publications.  Probably you would think "Facebook" or "Twitter" but this is an interesting client.  Their cons…
Introduction In my previous article (http://www.experts-exchange.com/Microsoft/Development/MS-SQL-Server/SSIS/A_9150-Loading-XML-Using-SSIS.html) I showed you how the XML Source component can be used to load XML files into a SQL Server database, us…
This Micro Tutorial demonstrates using Microsoft Excel pivot tables, how to reverse engineer competitors' marketing strategies through backlinks.
Windows 10 is mostly good. However the one thing that annoys me is how many clicks you have to do to dial a VPN connection. You have to go to settings from the start menu, (2 clicks), Network and Internet (1 click), Click VPN (another click) then fi…

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question