简体   繁体   中英

Renaming Child Nodes in XML file using C#?

I am having a problem renaming child nodes in xml files using c#.

This is my xml file:

<?xml version="1.0" encoding="ISO-8859-1"?>
<ZACAC01>
  <IDOC BEGIN="1">
    <ZACGPIAD SEGMENT="1">
      <IDENTIFIER>D000</IDENTIFIER>
      <CUST_DEL_NO/>
      <CUST_DEL_DATE/>
      <TRUCKNO/>
      <DRIVERNAME/>
      <DRIVERID/>
      <RESPONS_OFF/>
      <CONFIRM_DATE>20/01/13</CONFIRM_DATE>
      <SERIAL_NO>2</SERIAL_NO>
      <SERIAL_CHAR/>
      <DEL_INFO1/>
      <QTY>0</QTY>
      <DEL_INFO2/>
      <QTY>0</QTY>
      <DEL_INFO3/>
      <QTY>0</QTY>
      <TRANS_COMPANY>0</TRANS_COMPANY>
    </ZACGPIAD>
  </IDOC>
</ZACAC01>

And below is my requirement:

<?xml version="1.0" encoding="ISO-8859-1"?>
<ZACAC01>
  <IDOC BEGIN="1">
    <ZACGPIADD SEGMENT="1">
      <IDENTIFIER>D000</IDENTIFIER>
      <CUST_DEL_NO/>
      <CUST_DEL_DATE/>
      <TRUCKNO/>
      <DRIVERNAME/>
      <DRIVERID/>
      <RESPONS_OFF/>
      <CONFIRM_DATE>20/01/13</CONFIRM_DATE>
      <SERIAL_NO>2</SERIAL_NO>
      <SERIAL_CHAR/>
      <DEL_INFO1/>
      <QTY1>0</QTY1>
      <DEL_INFO2/>
      <QTY2>0</QTY2>
      <DEL_INFO3/>
      <QTY3>0</QTY3>
      <TRANS_COMPANY>0</TRANS_COMPANY>
    </ZACGPIADD>
  </IDOC>
</ZACAC01>

I am able to change the segment tag <ZACGPIAD> to this <ZACGPIADD> using the following code:

XmlDocument xmlDoc = new XmlDocument(); 
xmlDoc.Load(srcfile);
var root = xmlDoc.GetElementsByTagName("IDOC")[0];
var oldElem = root.SelectSingleNode("ZACGPIAD");
var newElem = xmlDoc.CreateElement("ZACGPIADD");
root.ReplaceChild(newElem, oldElem);

while (oldElem.ChildNodes.Count != 0)
{
    newElem.AppendChild(oldElem.ChildNodes[0]);
}
while (oldElem.Attributes.Count != 0)
{
    newElem.Attributes.Append(oldElem.Attributes[0]);
}
xmlDoc.Save(desfile);

But I can't change the <QTY> tag to <QTY1> , <QTY2> , <QTY3>

How can I do this?

I think you have the answer right in your code. You can use SelectSingleNode to pull the first <QTY> element with this:

var qtyNode = root.SelectSingleNode("ZACAC01/IDOC/ZACGPIADD/QTY[1]") 

then use ReplaceChild on it's parent node. Then do the same for the second and third <QTY> nodes, replacing the '1' with '2' and '3' respectively.

You can use XDocument and operate on XElements which expose setter for node name (so you can simply set new name instead of doing node replacements):

var doc = XDocument.Load(srcfile);
var zacgpidNode = doc.Descendants("ZACGPIAD").First();
zacgpidNode.Name = "ZACGPIADD";
// now rename all QTY nodes
var qtyNodes = zacgpidNode.Elements("QTY").ToArray();
for (int i = 0; i < qtyNodes.Length; i++)
{
    qtyNodes[i].Name = string.Format("{0}{1}", qtyNodes[i].Name, i+1);
}

doc.Save(desfile);

Having Descendants("ZACGPIAD").First() might not be suitable if your document structure is different than what you've shown in example. You can use XPathSelectElement method to have more control over what you'll be extracting:

var node = doc.XPathSelectElement("//IDOC[@BEGIN='1']/ZACGPIAD[@SEGMENT='1']");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM