Solved

How to Rename an XmlNode and all its Children

Posted on 2003-11-21
4
6,325 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Configure a Bean in an XML file 4 56
what are list of ebay api errors 1 48
xml with php question 5 53
How do i delete the last node in an xml in T-SQL 7 29
The Problem How to write an Xquery that works like a SQL outer join, providing placeholders for absent data on the outer side?  I give a bit more background at the end. The situation expressed as relational data Let’s work through this.  I’ve …
Many times as a report developer I've been asked to display normalized data such as three rows with values Jack, Joe, and Bob as a single comma-separated string such as 'Jack, Joe, Bob', and vice versa.  Here's how to do it. 
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…
Are you ready to implement Active Directory best practices without reading 300+ pages? You're in luck. In this webinar hosted by Skyport Systems, you gain insight into Microsoft's latest comprehensive guide, with tips on the best and easiest way…

751 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