Solved

How to Rename an XmlNode and all its Children

Posted on 2003-11-21
4
6,162 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

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

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…
I was working on a PowerPoint add-in the other day and a client asked me "can you implement a feature which processes a chart when it's pasted into a slide from another deck?". It got me wondering how to hook into built-in ribbon events in Office.
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

705 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

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now