VS C# Writing XML

I have just begun looking into how to write an xml file using visual studio c#. I came across this sample code and I can see I need to define 'book' someplace.  How do I correct this code to define the proper structure for book? It has the Title, Author.Name, Publisher, Price attributes.

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.IndentChars = ("    ");
            settings.CloseOutput = true;
            settings.OmitXmlDeclaration = true;
            using (XmlWriter writer = XmlWriter.Create("books.xml", settings))
            {
                writer.WriteStartElement("book");
                writer.WriteElementString("title", book.Title);
                writer.WriteElementString("author", book.Author.Name);
                writer.WriteElementString("publisher", book.Publisher);
                writer.WriteElementString("price", book.Price.ToString());
                writer.WriteEndElement();
                writer.Flush();
rwheeler23Asked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
käµfm³d 👽Connect With a Mentor Commented:
Honestly, I would consider using XML serialization for this task. I wrote a couple of articles on the subject some time back, complete with terrible jokes:

http://www.experts-exchange.com/Programming/Languages/.NET/A_3024-Introduction-to-XML-Serialization-in-NET.html
http://www.experts-exchange.com/Programming/Languages/.NET/A_3041-Writing-a-Class-Struct-to-be-XML-Serialized-and-Creating-a-Class-from-a-Schema.html

With serialization, you already have your C# structure, and you just dump it out to XML into the intended structure, typically with minimal changes to the C# code.

However, to answer the question you asked:

using (XmlWriter writer = XmlWriter.Create("books.xml", settings))
{
    writer.WriteStartElement("books");
    writer.WriteStartElement("book");
    writer.WriteStartAttribute("ISBN");
    writer.WriteValue(book.ISBN);
    writer.WriteEndAttribute();
    writer.WriteElementString("title", book.Title);
    writer.WriteStartElement("author");
    writer.WriteStartElement("first-name");
    writer.WriteValue(book.Author.Name);
    writer.WriteEndElement();
    writer.WriteElementString("publisher", book.Publisher);
    writer.WriteElementString("price", book.Price.ToString());
    writer.WriteEndElement();
    writer.WriteEndElement();
    writer.Flush();
}

Open in new window


Any time you call WriteStartElement, you have to, at some point, call WriteEndElement; where you do so depends on what you are trying to output in terms of the XML. (The same goes for WriteStartAttribute.) In the above, I call a WriteStartElement for "books", and at the end of the whole thing I call a corresponding WriteEndElement. The reason? I want the stuff in between to be a part of the <books> element that is output, so I don't want to "close" the <books> element before I write all of the other stuff.

You don't need an "WriteEnd***" call for the WriteElementString calls--they are more or less self-closing.

The above code generated:

Screenshot
0
 
käµfm³d 👽Commented:
It would help if you showed the XML structure you are trying to achieve.
0
 
rwheeler23Author Commented:
My apologies. Here it is:

<?xml version="1.0" encoding="utf-8" ?>
<!-- Books.xml stores information about Mahesh Chand and related books -->
<books>
  <book ISBN="9831123212" yearpublished="2002">
    <title>A Programmer's Guide to ADO.NET using C#</title>
    <author>
      <first-name>Mahesh</first-name>
      <last-name>Chand</last-name>
    </author>
    <publisher>Apress</publisher>
    <price>44.99</price>
  </book>
</books>
0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

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.

 
rwheeler23Author Commented:
Excellent. Thank you.
0
 
Daniel Van Der WerkenIndependent ConsultantCommented:
Kaufmed's answer is the correct answer. However, I wonder if your actual question is more basic. You need a class or structure defined that has the object you want, right?

I came across this sample code and I can see I need to define 'book' someplace.  How do I correct this code to define the proper structure for book? It has the Title, Author.Name, Publisher, Price attributes.

First, you need to create your classes:
    public class Author
    {
        public struct AuthorName
        {
            [XmlElement("first-name")]
            public string First_Name;
            [XmlElement("last-name")]
            public string Last_Name;
        };

        private AuthorName name = new AuthorName();
        public AuthorName Name
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
            }
        }

        public Author(string first, string last)
        {
            name = new AuthorName();
            name.First_Name = first;
            name.Last_Name = last;
        }

    }

    public class Book
    {
        public string Title { get; set; }
        public string Publisher { get; set; }
        public decimal Price { get; set; }
        public Author Author { get; set; }
        public string ISBN { get; set; }
        public string Year_Published { get; set; }
    }

Open in new window


Next, the code to write this is almost exactly like kaufmed's solution:

       
public void doIt()
        {
            Book book = new Book();
            book.Title = "A Programmer's Guide to ADO.NET using C#";
            book.Price = 44.99M;
            book.Publisher = "Apress";
            book.Author = new Author("Mahesh", "Chanad");
            book.ISBN = "9831123212";
            book.Year_Published = "2002";

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.IndentChars = ("    ");
            settings.CloseOutput = true;
            settings.OmitXmlDeclaration = true;
            using (XmlWriter writer = XmlWriter.Create(@"C:\books.xml", settings))
            {
                writer.WriteStartElement("books");
                writer.WriteStartElement("book");
                writer.WriteAttributeString("ISBN", book.ISBN);
                writer.WriteAttributeString("Year-Published", book.Year_Published);
                writer.WriteElementString("title", book.Title);
                writer.WriteStartElement("author");
                writer.WriteElementString("first-name", book.Author.Name.First_Name);
                writer.WriteElementString("last-name", book.Author.Name.Last_Name);
                writer.WriteEndElement();
                writer.WriteElementString("publisher", book.Publisher);
                writer.WriteElementString("price", book.Price.ToString());
                writer.WriteEndElement();
                writer.WriteEndElement();
                writer.Flush();

            }
        }

Open in new window


Here's the actual output from this code:

<books>
    <book ISBN="9831123212" Year-Published="2002">
        <title>A Programmer's Guide to ADO.NET using C#</title>
        <author>
            <first-name>Mahesh</first-name>
            <last-name>Chanad</last-name>
        </author>
        <publisher>Apress</publisher>
        <price>44.99</price>
    </book>
</books>

Open in new window

0
 
rwheeler23Author Commented:
That though dawned on me as I working on some other code. I continue to be impressed by the knowledge that is shared on this website. Thanks to all of you my code gets cleaner and more efficient with each application.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.