using System;
using System.Xml;
using System.IO;
using System.Collections;
namespace XMLDemoCSharp
{
class XMLDemoCSharp
{ //Change bookfile to point to a valid path on your system, or Main will throw exceptions.
public static String bookfile = "//catalog.xml";
[STAThread]
static void Main(string[] args)
{
UserInterface UI = new UserInterface();
ArrayList books = Book.LoadBooks(new FileStream(bookfile,FileMode.OpenOrCreate));
UI.ShowMenu(books);
}
}
class UserInterface
{
private static string formatString = "Book: {0} /n/t Title: {1} /n/t Author: {2} /n/t Price: {3} /n/t PubDate: {4} /n/t Description: {5}";
private static string menuString = "Menu:/n1 - View the book list/n2 - Add a new book/n3 - Save the book list/n/n99 - Quit";
private static string cancelMessage = "***Book addition cancelled***";
private static string newBookString = "/nAdding new book - Press [Enter] for any item to cancel/nBook ID:";
public void ShowMenu(ArrayList books)
{
int choice = 0;
//Main menu loop
while (choice != 99)
{
Console.WriteLine(menuString);
string s = Console.ReadLine();
try
{
choice = Int32.Parse(s);
}
catch
{
choice = -1;
}
switch (choice)
{
case 1:
this.DisplayBooks(books);
break;
case 2:
Book b = this.AddNewBook();
if (b != null)
books.Add(b);
break;
case 3:
Book.SaveBooks(books, new StreamWriter(XMLDemoCSharp.bookfile).BaseStream);
break;
case 99:
break;
default:
Console.WriteLine("Huh?");
break;
}
}
}
public Book AddNewBook()
{
//prompt the user for all data needed to create a new book
Console.WriteLine(newBookString);
string BookId = Console.ReadLine();
Book b;
if (!BookId.Equals(""))
{
b = new Book(BookId);
}
else
{
//user cancelled
Console.WriteLine(cancelMessage);
return null;
}
int i =0; bool cancelled = false;
while (cancelled != true && i < 7)
{
switch (++i)
{
case 1:
cancelled = getTitle(b);
break;
case 2:
cancelled = getAuthor(b);
break;
case 3:
cancelled = getPrice(b);
break;
case 4:
cancelled = getGenre(b);
break;
case 5:
cancelled = getPubDate(b);
break;
case 6:
cancelled = getDescription(b);
break;
}
}
if (cancelled)
{
Console.WriteLine(cancelMessage);
return null;
}
else
{
Console.WriteLine("Book successfully added.");
return b;
}
}
private bool getTitle(Book b)
{
//prompt for the title of the new book
Console.WriteLine("Title: ");
b.Title = Console.ReadLine();
return (b.Title.Equals(""));
}
private bool getAuthor(Book b)
{
//prompt for the author of the new book
Console.WriteLine("Author: ");
b.Author = Console.ReadLine();
return (b.Author.Equals(""));
}
private bool getPrice(Book b)
{
//prompt for the price of the new book
bool parsed = false;
while (!parsed)
{
//keep looping until we get valid input
//or the user presses [Enter] to abort
Console.WriteLine("Price: ");
string price = Console.ReadLine();
if (!price.Equals(""))
{
try
{
b.Price = Double.Parse(price);
parsed = true;
}
catch
{
Console.WriteLine("Unable to parse your entry, try again.");
}
}
else
{
return true;
}
}
return false;
}
private bool getGenre(Book b)
{
//prompt for the genre of the new book
Console.WriteLine("Genre: ");
b.Genre = Console.ReadLine();
return (b.Genre.Equals(""));
}
private bool getPubDate(Book b)
{
//prompt for the pub date of the new book
bool parsed = false;
while(!parsed)
{
//keep looping until we get valid input
//or the user presses [Enter] to abort
Console.WriteLine("Publish Date (mm/dd/yyyy): ");
string date = Console.ReadLine();
if (!date.Equals(""))
{
try
{
b.PublishDate = DateTime.Parse(date);
parsed = true;
}
catch
{
Console.WriteLine("Unable to parse your entry, try again.");
}
}
else
{
return true;
}
}
return false;
}
private bool getDescription(Book b)
{
//prompt for the description of the new book
Console.WriteLine("Description: ");
b.Description = Console.ReadLine();
return (b.Description.Equals(""));
}
public void DisplayBooks(ArrayList books)
{
if (books.Count == 0)
{
System.Console.WriteLine("***No books in list***");
}
else
{
//display all books in the list
foreach (Book book in books)
{
System.Console.WriteLine(formatString,
book.ID, book.Title, book.Author, book.Price,
book.PublishDate.ToShortDateString(), book.Description);
}
}
}
}
class Book
{
private string id;
private string title;
private string author;
private string genre;
private string description;
private double price;
private DateTime pubdate;
//Static Methods for loading and saving the book list
public static ArrayList LoadBooks(Stream stream)
{
//Could also open a file using a URL, but streams are more flexible
XmlTextReader reader = new XmlTextReader(stream);
reader.WhitespaceHandling = WhitespaceHandling.None;
ArrayList al = new ArrayList();
if (stream.Length != 0)
{
//read to the first book element
reader.ReadStartElement();
//continue reading until we hit the closing catalog element
//XmlReader does a depth-first traversal, same as reading
//the text for a document from top to bottom, so </catalog>
//is the last tag it sees before hitting EOF
while (!reader.LocalName.Equals("catalog"))
{
//now on the Book element, read the ID attribute
string bookid = reader.GetAttribute("id");
//move to the first nested element of <book>
reader.Read();
//now keep reading until we hit </book> which is the
//end of the book.
Book b = new Book(bookid);
while (!reader.LocalName.Equals("book"))
{
//figure out what element we are on by examining
//the LocalName property.
string localName = reader.LocalName;
//move to the data node
reader.Read();
//read the data from the data node
string data = reader.ReadString();
//now figure out where to put the data based on the element name
//unknown element names fall through and are skipped.
if (localName.Equals("author"))
{
b.Author = data;
}
else if (localName.Equals("title"))
{
b.Title = data;
}
else if (localName.Equals("genre"))
{
b.Genre = data;
}
else if (localName.Equals("price"))
{
b.Price = Double.Parse(data);
}
else if (localName.Equals("publish_date"))
{
b.PublishDate = DateTime.Parse(data);
}
else if (localName.Equals("description"))
{
b.Description = data;
}
//move to the next node, which takes us to the next element
reader.Read();
}
al.Add((object) b);
//now we are on </book>, need to read to the next element.
//if it's <book> we read the next book, if it's </catalog>
//we're done
reader.Read();
}
}
reader.Close();
stream.Close();
return al;
}
public static void SaveBooks(ArrayList books, Stream stream)
{
//could also open a file based on a URL here, but streams
//are far more flexible.
XmlTextWriter writer = new XmlTextWriter(stream, System.Text.Encoding.ASCII);
//write the <xml version="1.0"> element
writer.WriteStartDocument();
//write the root <catalog> element
writer.WriteStartElement("catalog");
foreach (Book b in books)
{
//write the <book> element
writer.WriteStartElement("book");
//set the ID attribute
writer.WriteAttributeString("id", b.ID);
//WriteElementString lets you write an element and
//its data in one call.
writer.WriteElementString("author", b.Author);
writer.WriteElementString("title", b.Title);
writer.WriteElementString("genre", b.Genre);
writer.WriteElementString("price", b.Price.ToString());
//get the date into yyyy-mm-dd format
//might be better to use a StringBuilder instead of a string
string date = b.PublishDate.Year + "-" + b.PublishDate.Month + "-" + b.PublishDate.Day;
writer.WriteElementString("publish_date", date);
writer.WriteElementString("description", b.Description);
//close the book element: </book>
writer.WriteEndElement();
}
//close the catalog element </catalog>
writer.WriteEndElement();
writer.Flush();
writer.Close();
stream.Close();
}
//ctor
public Book(String id)
{
this.id = id;
}
//Property Accessors
public string ID
{
get {return this.id;}
set {this.id = value;}
}
public string Title
{
get {return this.title;}
set {this.title = value;}
}
public string Author
{
get {return this.author;}
set {this.author = value;}
}
public string Genre
{
get {return this.genre;}
set {this.genre = value;}
}
public string Description
{
get {return this.description;}
set {this.description = value;}
}
public double Price
{
get {return this.price;}
set {this.price = value;}
}
public DateTime PublishDate
{
get {return this.pubdate;}
set {this.pubdate = value;}
}
}
}
using System.Xml;
using System.IO;
using System.Collections;
namespace XMLDemoCSharp
{
class XMLDemoCSharp
{ //Change bookfile to point to a valid path on your system, or Main will throw exceptions.
public static String bookfile = "//catalog.xml";
[STAThread]
static void Main(string[] args)
{
UserInterface UI = new UserInterface();
ArrayList books = Book.LoadBooks(new FileStream(bookfile,FileMode.OpenOrCreate));
UI.ShowMenu(books);
}
}
class UserInterface
{
private static string formatString = "Book: {0} /n/t Title: {1} /n/t Author: {2} /n/t Price: {3} /n/t PubDate: {4} /n/t Description: {5}";
private static string menuString = "Menu:/n1 - View the book list/n2 - Add a new book/n3 - Save the book list/n/n99 - Quit";
private static string cancelMessage = "***Book addition cancelled***";
private static string newBookString = "/nAdding new book - Press [Enter] for any item to cancel/nBook ID:";
public void ShowMenu(ArrayList books)
{
int choice = 0;
//Main menu loop
while (choice != 99)
{
Console.WriteLine(menuString);
string s = Console.ReadLine();
try
{
choice = Int32.Parse(s);
}
catch
{
choice = -1;
}
switch (choice)
{
case 1:
this.DisplayBooks(books);
break;
case 2:
Book b = this.AddNewBook();
if (b != null)
books.Add(b);
break;
case 3:
Book.SaveBooks(books, new StreamWriter(XMLDemoCSharp.bookfile).BaseStream);
break;
case 99:
break;
default:
Console.WriteLine("Huh?");
break;
}
}
}
public Book AddNewBook()
{
//prompt the user for all data needed to create a new book
Console.WriteLine(newBookString);
string BookId = Console.ReadLine();
Book b;
if (!BookId.Equals(""))
{
b = new Book(BookId);
}
else
{
//user cancelled
Console.WriteLine(cancelMessage);
return null;
}
int i =0; bool cancelled = false;
while (cancelled != true && i < 7)
{
switch (++i)
{
case 1:
cancelled = getTitle(b);
break;
case 2:
cancelled = getAuthor(b);
break;
case 3:
cancelled = getPrice(b);
break;
case 4:
cancelled = getGenre(b);
break;
case 5:
cancelled = getPubDate(b);
break;
case 6:
cancelled = getDescription(b);
break;
}
}
if (cancelled)
{
Console.WriteLine(cancelMessage);
return null;
}
else
{
Console.WriteLine("Book successfully added.");
return b;
}
}
private bool getTitle(Book b)
{
//prompt for the title of the new book
Console.WriteLine("Title: ");
b.Title = Console.ReadLine();
return (b.Title.Equals(""));
}
private bool getAuthor(Book b)
{
//prompt for the author of the new book
Console.WriteLine("Author: ");
b.Author = Console.ReadLine();
return (b.Author.Equals(""));
}
private bool getPrice(Book b)
{
//prompt for the price of the new book
bool parsed = false;
while (!parsed)
{
//keep looping until we get valid input
//or the user presses [Enter] to abort
Console.WriteLine("Price: ");
string price = Console.ReadLine();
if (!price.Equals(""))
{
try
{
b.Price = Double.Parse(price);
parsed = true;
}
catch
{
Console.WriteLine("Unable to parse your entry, try again.");
}
}
else
{
return true;
}
}
return false;
}
private bool getGenre(Book b)
{
//prompt for the genre of the new book
Console.WriteLine("Genre: ");
b.Genre = Console.ReadLine();
return (b.Genre.Equals(""));
}
private bool getPubDate(Book b)
{
//prompt for the pub date of the new book
bool parsed = false;
while(!parsed)
{
//keep looping until we get valid input
//or the user presses [Enter] to abort
Console.WriteLine("Publish Date (mm/dd/yyyy): ");
string date = Console.ReadLine();
if (!date.Equals(""))
{
try
{
b.PublishDate = DateTime.Parse(date);
parsed = true;
}
catch
{
Console.WriteLine("Unable to parse your entry, try again.");
}
}
else
{
return true;
}
}
return false;
}
private bool getDescription(Book b)
{
//prompt for the description of the new book
Console.WriteLine("Description: ");
b.Description = Console.ReadLine();
return (b.Description.Equals(""));
}
public void DisplayBooks(ArrayList books)
{
if (books.Count == 0)
{
System.Console.WriteLine("***No books in list***");
}
else
{
//display all books in the list
foreach (Book book in books)
{
System.Console.WriteLine(formatString,
book.ID, book.Title, book.Author, book.Price,
book.PublishDate.ToShortDateString(), book.Description);
}
}
}
}
class Book
{
private string id;
private string title;
private string author;
private string genre;
private string description;
private double price;
private DateTime pubdate;
//Static Methods for loading and saving the book list
public static ArrayList LoadBooks(Stream stream)
{
//Could also open a file using a URL, but streams are more flexible
XmlTextReader reader = new XmlTextReader(stream);
reader.WhitespaceHandling = WhitespaceHandling.None;
ArrayList al = new ArrayList();
if (stream.Length != 0)
{
//read to the first book element
reader.ReadStartElement();
//continue reading until we hit the closing catalog element
//XmlReader does a depth-first traversal, same as reading
//the text for a document from top to bottom, so </catalog>
//is the last tag it sees before hitting EOF
while (!reader.LocalName.Equals("catalog"))
{
//now on the Book element, read the ID attribute
string bookid = reader.GetAttribute("id");
//move to the first nested element of <book>
reader.Read();
//now keep reading until we hit </book> which is the
//end of the book.
Book b = new Book(bookid);
while (!reader.LocalName.Equals("book"))
{
//figure out what element we are on by examining
//the LocalName property.
string localName = reader.LocalName;
//move to the data node
reader.Read();
//read the data from the data node
string data = reader.ReadString();
//now figure out where to put the data based on the element name
//unknown element names fall through and are skipped.
if (localName.Equals("author"))
{
b.Author = data;
}
else if (localName.Equals("title"))
{
b.Title = data;
}
else if (localName.Equals("genre"))
{
b.Genre = data;
}
else if (localName.Equals("price"))
{
b.Price = Double.Parse(data);
}
else if (localName.Equals("publish_date"))
{
b.PublishDate = DateTime.Parse(data);
}
else if (localName.Equals("description"))
{
b.Description = data;
}
//move to the next node, which takes us to the next element
reader.Read();
}
al.Add((object) b);
//now we are on </book>, need to read to the next element.
//if it's <book> we read the next book, if it's </catalog>
//we're done
reader.Read();
}
}
reader.Close();
stream.Close();
return al;
}
public static void SaveBooks(ArrayList books, Stream stream)
{
//could also open a file based on a URL here, but streams
//are far more flexible.
XmlTextWriter writer = new XmlTextWriter(stream, System.Text.Encoding.ASCII);
//write the <xml version="1.0"> element
writer.WriteStartDocument();
//write the root <catalog> element
writer.WriteStartElement("catalog");
foreach (Book b in books)
{
//write the <book> element
writer.WriteStartElement("book");
//set the ID attribute
writer.WriteAttributeString("id", b.ID);
//WriteElementString lets you write an element and
//its data in one call.
writer.WriteElementString("author", b.Author);
writer.WriteElementString("title", b.Title);
writer.WriteElementString("genre", b.Genre);
writer.WriteElementString("price", b.Price.ToString());
//get the date into yyyy-mm-dd format
//might be better to use a StringBuilder instead of a string
string date = b.PublishDate.Year + "-" + b.PublishDate.Month + "-" + b.PublishDate.Day;
writer.WriteElementString("publish_date", date);
writer.WriteElementString("description", b.Description);
//close the book element: </book>
writer.WriteEndElement();
}
//close the catalog element </catalog>
writer.WriteEndElement();
writer.Flush();
writer.Close();
stream.Close();
}
//ctor
public Book(String id)
{
this.id = id;
}
//Property Accessors
public string ID
{
get {return this.id;}
set {this.id = value;}
}
public string Title
{
get {return this.title;}
set {this.title = value;}
}
public string Author
{
get {return this.author;}
set {this.author = value;}
}
public string Genre
{
get {return this.genre;}
set {this.genre = value;}
}
public string Description
{
get {return this.description;}
set {this.description = value;}
}
public double Price
{
get {return this.price;}
set {this.price = value;}
}
public DateTime PublishDate
{
get {return this.pubdate;}
set {this.pubdate = value;}
}
}
}