tags:

views:

370

answers:

7

How to write or generate an XML file using C# to get the result below?

<?xml version="1.0" encoding="UTF-8"?>
<pages>
<page name="Page Name 1" url="/page-1/" />
<page name="Page Name 2" url="/page-2/" />
<page name="Page Name 3" url="/page-3/" />
<page name="Page Name 4" url="/page-4/" />
</pages>
+9  A: 
using System.Linq;
using System.Xml;
using System.Xml.Linq;

// ...

using (var writer = XmlWriter.Create("output.xml"))
     new XDocument(
        new XDeclaration("1.0", "UTF-8", null),
        new XElement("pages",
            Enumerable.Range(1, 4)
                .Select(i => new XElement("page",
                                  new XAttribute("name", "Page Name " + i),
                                  new XAttribute("url", "/page-" + i + "/"))))
     ).WriteTo(writer);
Mehrdad Afshari
Pretty code :P~~~
Jon
Really pretty code.
crauscher
+3  A: 

I guess something like this:

System.Xml.XmlTextWriter writer = new System.Xml.XmlTextWriter(Server.MapPath("pages.xml"), System.Text.Encoding.UTF8);

     writer.WriteStartDocument();
     writer.WriteStartElement("pages");

        writer.WriteStartElement("page");
     writer.WriteAttributeString("name", "Page name 1");
     writer.WriteAttributeString("url", "Page url 1");
     writer.WriteEndElement();

        writer.WriteStartElement("page");
     writer.WriteAttributeString("name", "Page name 2 ");
     writer.WriteAttributeString("url", "Page url 2");
     writer.WriteEndElement();

        writer.WriteStartElement("page");
     writer.WriteAttributeString("name", "Page name 3");
     writer.WriteAttributeString("url", "Page url 3");
     writer.WriteEndElement();

     writer.WriteEndElement();
     writer.WriteEndDocument();
     writer.Close();
meep
I am more in favour of this than the "LINQ method" (if I can be out of line to say that) as the question asks specifically about how to write an XML document. If you want to query and play around with an XML document then Mehrdad's answer would be more relevant. Either works I guess.
Andrew Weir
+2  A: 

If you are using the .NET framework 2.0, you should use the XmlWriter class to write XML, else you can use the XmlTextWriter.

If you are on .NET 3+, you can use the XDocument class of the System.Xml.Linq namespace.

Cerebrus
+5  A: 

A rather straight-forward way could be like this:

XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.UTF8;
settings.Indent = true;
using (XmlWriter writer = XmlWriter.Create(@"c:\path\file.xml", settings))
{

    writer.WriteStartElement("pages");

    for (int i = 1; i < 5; i++)
    {
        writer.WriteStartElement("page");
        writer.WriteAttributeString("name", "Page Name " + i.ToString());
        writer.WriteAttributeString("url", string.Format("/page-{0}/", i));
        writer.WriteEndElement(); // page
    }
    writer.WriteEndElement(); // pages
}
Fredrik Mörk
Exactly the method I would use (pre-LInQ). +1
Cerebrus
A: 

A couple of points on the answers given. For an XML document of that size, XDocument is pretty inefficient way to handle it. At least, with my understanding of what XDocument should be used for. If your handling large documents in memory and you want to query them with LINQ, then XmlDocument/XDocument is the way forward. If I'm wrong, please correct me and accept my apologies.

Secondly, again with my understanding, your XML structure is wrong. Please do correct me if I haven't got this right but attributes are meta-data describing what the element value is. It's not to be used as the value itself. For your case, your structure should be something like..

<pages>
    <page>
        <name href="url">Page Name 1</name>
    </page>
</pages>

Or if you want to be really anal

<pages>
    <page>
        <name>Page Name 1
        <url>http://page/&lt;/url&gt;
    </page>
</pages>

I fear this answer will open up the dreaded element vs attribute debate (which shouldn't exist but always does.)

EDIT: This isn't a direct answer to the question; I feel it is closer to a metacomment (a comment about the answers of the question). I wasn't sure where to put it if it was even relevant but I think it's worth mentioning.

Andrew Weir
+1  A: 
using System.Xml;
//...
XmlDocument xmldoc = new XmlDocument();
XmlElement pages = xmldoc.CreateElement("pages");
XmlElement page = null;

for(int i = 1; i <= 4; i++)
{
    page = xmldoc.CreateElement("page");
    page.SetAttribute("name", "Page Name " + i);
    page.SetAttribute("url", "/page-" + i + "/");
    pages.AppendChild(page);
}

xmldoc.AppendChild(xmldoc.CreateXmlDeclaration("1.0", "UTF-8", null));
xmldoc.AppendChild(pages);
xmldoc.Save("output.xml");
iKomplex
A: 

You could also look at XML Data Binding. This approach would give you code that looks more like this.

Pages pages = new Pages();
for(int i=1; i<=4;i++)
{
    Page p = new Page();
    p.name = "Page Name " + i;
    p.url = "/page-" + i + "/";
    pages.Pages.Add(p);
}
Console.Write(pages.ToXml());

Have a look at "A closer look at XML Data Binding"

Here is also a good list of xml data binding tools

Colin