kanabut
kanabut

Reputation: 41

How i can write xml node in C#

i want to write text in xml file under tag "Engine" but right now it can write under tag "Service" here is my code

        XmlDocument doc = new XmlDocument();
        doc.Load(filename);
        XmlElement root = doc.DocumentElement;
        XmlNodeList elemList = root.GetElementsByTagName("Engine");
            for (int i = 0; i < elemList.Count; i++)

            {
                XmlNode head = doc.CreateNode(XmlNodeType.Element, "Host", null);
                XmlAttribute na = doc.CreateAttribute("name");
                na.Value = "url";

                XmlNode nodeTitle = doc.CreateElement("Valve");
                XmlAttribute className = doc.CreateAttribute("className");
                className.Value = "org.apache.catalina.valves.AccessLogValve";

                doc.DocumentElement.LastChild.AppendChild(head);
                doc.Save(filename); 
            }

here is xml file

 <Server>
      <Service name="Catalina">
          <Engine name="Catalina" >
            <Host name="localhost">
              <Valve  />
            </Host>
          </Engine>
      </Service>
 </Server>

Upvotes: 2

Views: 5203

Answers (3)

jdweng
jdweng

Reputation: 34421

I like XML Linq

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?><Server><Service name=\"Catalina\">" +
                "<Engine name=\"Catalina\"></Engine>" +
                "<Engine name=\"Catalina\"></Engine>" +
                "<Engine name=\"Catalina\"></Engine>" +
                "</Service></Server>";

            XDocument doc = XDocument.Parse(xml);

            foreach(XElement engine in doc.Descendants("Engine"))
            {
                object[] newNode =  { new XElement("Host", new XAttribute("name", "localhost")), new XElement("Value")};
                engine.Add(newNode);
            }

        }
    }
}

Upvotes: 0

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236188

You are not using Engine elements in your code. You just adding Host elements to the last child of xml root (Service). Also keep in mind that if you have several Engine elements, you will append several Host elements with exactly same values.

First of all, I suggest you to use LINQ to XML. E.g. adding Host element to first (if any) Engine element looks like:

var xdoc = XDocument.Load(filename);

var engine = xdoc.Root.Descendants("Engine").FirstOrDefault();

if (engine != null)
{
    engine.Add(new XElement("Host", 
        new XAttribute("name", "url"),
        new XElement("Valve",
            new XAttribute("className", "org.apache.catalina.valves.AccessLogValve"))));

    xdoc.Save(filename);
}

For your sample xml result will be

<Server>
  <Service name="Catalina">
    <Engine name="Catalina">
      <Host name="localhost">
        <Valve />
      </Host>
      <Host name="url">
        <Valve className="org.apache.catalina.valves.AccessLogValve" />
      </Host>
    </Engine>
  </Service>
</Server>

If you want to modify each Engine element, then just use loop:

foreach(var engine in xdoc.Root.Descendants("Engine"))
  // add host to engine here

Upvotes: 1

Arie
Arie

Reputation: 5373

    XmlDocument doc = new XmlDocument();
    doc.Load(filename);
    XmlElement root = doc.DocumentElement;
    XmlNodeList elemList = root.GetElementsByTagName("Engine");
        for (int i = 0; i < elemList.Count; i++)

        {
            XmlNode head = doc.CreateNode(XmlNodeType.Element, "Host", null);
            XmlAttribute na = doc.CreateAttribute("name");
            na.Value = "url";

            // nodeTitle is not appended the document:
            //XmlNode nodeTitle = doc.CreateElement("Valve");
            // className is not appended to any node either:
            //XmlAttribute className = doc.CreateAttribute("className");
            //className.Value = "org.apache.catalina.valves.AccessLogValve";

            // this line will add your node to the last node of your document:  
            //doc.DocumentElement.LastChild.AppendChild(head);
            // if you want to add it to every "Engine" node:
            elemList[i].AppendChild(head);
            //doc.Save(filename); 
        }
        // save at the end, when you're done with the document:
        doc.Save(filename); 

Upvotes: 0

Related Questions