2

I am using the below code to rename the xmlnode name dynamically. It's looping though the xml just fine, but it does not change the node name. Please help me to do this.

Sample XML doucment

- <NewDataSet>
- <Table5>
  <FLD_ID>62</FLD_ID> 
  <FLD_DATE>2013-03-12</FLD_DATE> 
  <FLD_MOD_DATE>2013-04-05</FLD_MOD_DATE> 
  <FLD_DESC>New Creation</FLD_DESC> 
  </Table5>
- </NewDataSet>

Needed XML DOCUMENT

- <rows>
- <row>
  <cell>62</cell> 
  <cell>2013-03-12</cell> 
  <cell>2013-04-05</cell> 
  <cell>New Creation</cell> 
  </row>
- </rows>

My code is here

XmlNode PackageListNode = hst_doc.SelectSingleNode("NewDataSet");
                XmlNodeList PackageNodeList = PackageListNode.SelectNodes("Table5");

                foreach (XmlNode node in PackageNodeList)
                {
                    node.Name.Replace("Table5", "row");

                    foreach (XmlNode ls in node)
                    {
                        ls.Name.Replace(ls.Name, "cell");

                    }
        }
2
  • string is immutable!!! Commented Apr 5, 2013 at 14:27
  • 1
    1. Honestly, it may be easier to just recreate another XML tree. 2. Make sure everything you're using supports nodes with same names at the same level. That can't be assumed. Ever. 3. Look into recursion for traversing XML trees. It may be more complicated and dense, but it may work out better in many circumstances. Commented Apr 5, 2013 at 14:36

3 Answers 3

3

As you can't replace element names in an XmlDocument... ...a replacement approach for your specific situation:

string srcXML = "<NewDataSet><Table5><FLD_ID>62</FLD_ID><FLD_DATE>2013-03-12</FLD_DATE><FLD_MOD_DATE>2013-04-05</FLD_MOD_DATE><FLD_DESC>New Creation</FLD_DESC></Table5></NewDataSet>";
var doc = new XmlDocument();
doc.LoadXml(srcXML);

XmlNode oldRoot = doc.SelectSingleNode("NewDataSet");
XmlNode newRoot = doc.CreateElement("rows");
doc.ReplaceChild(newRoot, oldRoot);

foreach (XmlNode childNode in oldRoot.ChildNodes)
{
    newRoot.AppendChild(childNode.CloneNode(true));
}

XmlNodeList PackageNodeList = newRoot.SelectNodes("Table5");

foreach (XmlNode node in PackageNodeList)
{
    var newNode = doc.CreateElement("row");
    newRoot.ReplaceChild(newNode, node);

    foreach (XmlNode childNode in node.ChildNodes)
    {
        var clonedChildNode = childNode.CloneNode(true);
        newNode.AppendChild(clonedChildNode);

        var newChildNode = doc.CreateElement("cell");
        newNode.ReplaceChild(newChildNode, clonedChildNode);

        foreach (XmlNode childChildNode in clonedChildNode.ChildNodes)
        {
            newChildNode.AppendChild(childChildNode.CloneNode(true));
        }                    
    }
}

Debug.Print(doc.OuterXml);
Sign up to request clarification or add additional context in comments.

3 Comments

can i change the root name NewDataSet to rows.
Edited my answer. Anyway.. as i rethought the question i think, maybe - depending on the "real world usage" of this solution - the more elegant way of transforming your xml input would be using XSL Transformation as discussed here: link
If you are not bound to the XmlDocument and can make use of the .NET Framwork 3.5+ XDocument it's really way more pretty and usable as seen in the answer of Jeff Mercado.
1

Embrace LINQ, embrace it!

// load the document from a file
var doc = XDocument.Load(xmlPath);
var root = doc.Root;

// replace the root element with a new element
root.ReplaceWith(

    // create a new element with
    // the name "rows" with new children
    new XElement("rows",

        // replace all child elements of
        // the root with new elements
        root.Elements().Select(table =>

            // replace the current element with a new element
            // with the name "row" with the new children
            new XElement("row",

                // replace all child elements of the
                // current element with new elements
                table.Elements().Select(field =>

                    // replace the current element with a new element
                    // with the name "cell" with the same value
                    new XElement("cell",
                        (string)field
                    )
                )
            )
        )
    )
);

// save the document back to the file
doc.Save(xmlPath);

Comments

0

String.Replace returns a new string, so of course one would love to:

node.Name = node.Name.Replace("Table5", "row");

which might as well be

node.Name = "row";

however, if you look at the documentation it says that XmlNode.Name is purely a 'getter' and not a 'setter', so maybe you'll need to create whole new nodes to replace them, it depends on the actual implementation, since XmlNode is an abstract class.

  for (int i = 0; i < PackageNodeList.Count; ++i) XmlNode node in PackageNodeList)
            {
                XmlNode replacementNode = new XmlNode("row");

                foreach (XmlNode ls in node)
                {
                    XmlNode newCell = new XmlNode("cell");
                    newCell.Value = ls.Value;
                    replacementNode.AppendChild(newCell);
                }
                PackageNodeList[i] = replacementNode
                PackageNodeList[i].ParentNode.ReplaceChild(PackageNodeList[i], replacementNode);
    }

Comments

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.