Add Information To XML file in C# - c#

Say I have an XML Document that looks like this:
<BOOK>
<NAME>Home</NAME>
<ISBN>0-943396-04-2</ISBN>
<PRICE>$0.82</PRICE>
</BOOK>
And I have a program that has the purpose of allowing the user to add another book to the list... what code would I put on the Button I have titled "Add Book" to make it add another set of information?
So the end product would look like this:
<BOOK>
<NAME>Home</NAME>
<ISBN>0-943396-04-2</ISBN>
<PRICE>$0.82</PRICE>
</BOOK>
<BOOK>
<NAME>Work</NAME>
<ISBN>0-85131-041-9</ISBN>
<PRICE>$0.99</PRICE>
</BOOK>
I am using Microsoft Visual C# 2010 Express, if that helps.

firstly youll need to put a container around your books list so
<BOOKS>
<BOOK>
<NAME>Home</NAME>
<ISBN>0-943396-04-2</ISBN>
<PRICE>$0.82</PRICE>
</BOOK>
</BOOKS>
Then you'll need to parse it with something are you storing it in a file? if so then
XElement.Load(filename);
otherwise you can parse a string
XElement el = XElement.Parse(#"<BOOKS><BOOK>
<NAME>Home</NAME>
<ISBN>0-943396-04-2</ISBN>
<PRICE>$0.82</PRICE>
</BOOK></BOOKS>");
then create a and add a new book
var newBook = new XElement("BOOK", new[]
{
new XElement("NAME", "thename"),
new XElement("ISBN", "isbn"),
new XElement("PRICE", ".71")
});
el.Add(newBook);
and save it if you need to
el.Save(filename)
Reformatted comment below;
var el = XElement.Load("Ops.xml");
var newOp = new XElement("Operation", new[] {
new XElement("Operation Name", textBox2.Text),
new XElement("Operation Date", dateTimePicker1.Value)
});
el.Add(newOp);

Related

Can I get a distinct list of XML TagName using C#?

I have a very long xml file and I need to identify what are the distinct TagName in that xml file. I wonder if I can get it in my C# application with XmlDocument library.
In this example xml, I want to find all the TagName: bookstore, book genre, title, first name
<bookstore>
<book genre="novel">
<title>The Autobiography of Benjamin Franklin</title>
</book>
<book genre="novel">
<title>The Confidence Man</title>
<first-name>Herman</first-name>
</book>
</bookstore>
Parse it as an XDocument and you could do this:
var names = doc.Descendants().Select(e => e.Name.LocalName).Distinct();
This will give you the results (in some order):
bookstore
book
title
first-name
Otherwise if you must use an XmlDocument, you could do this:
var names = doc.DocumentElement
.SelectNodes("//*").Cast<XmlNode>()
.Select(e => e.LocalName)
.Distinct();
You can use HashSet to get distinct names. Moreover, it is very fast.
var doc = XDocument.Load("test.xml");
var set = new HashSet<string>();
foreach (var node in doc.Descendants())
{
set.Add(node.Name.LocalName);
foreach (var attr in node.Attributes())
set.Add(attr.Name.LocalName);
}
foreach (var name in set)
Console.WriteLine(name);

Join two children

I have this XML File:
<library>
<book ISBN="BSWE153" authors = "AC532" >
<title>Leraing XML</title>
<year>1995</year>
<publisher>W3C</publisher>
</book>
<author id="AC532">
<firstName>Hamdy</firstName>
<middleName/>
<lastName>Taha</lastName>
<nationality>Egypatian</nationality>
</author>
</library>
How to print the information of a book (with its authors information) given by its ISBN?
You can do that using XDocument, for example. You will need to
Parse your string (or load the file)
locate the book
read author Id (or ids?)
locate the author
nicely format it all together - with appropriate checks.
that is just a sketch:
const string xml = #"<?xml version=""1.0""?>
<library>
<book ISBN=""BSWE153"" authors = ""AC532"" >
<title>Leraing XML</title>
<year>1995</year>
<publisher>W3C</publisher>
</book>
<author id=""AC532"">
<firstName>Hamdy</firstName>
<middleName/>
<lastName>Taha</lastName>
<nationality>Egypatian</nationality>
</author>
</library>
";
var doc = XDocument.Parse(xml);
var book = doc.Root.Elements("book")
.FirstOrDefault(b => (string)b.Attribute("ISBN") == "BSWE153" );
var authorId = book.Attribute("authors").Value.ToString();
var author = doc.Root.Elements("author")
.FirstOrDefault(b => (string)b.Attribute("id") == authorId );
Console.WriteLine("{0} by {1} {2}",
book.Element("title").Value,
author.Element("firstName").Value,
author.Element("lastName").Value);

Create nodes from List<XElement> using linq

I want to create the following the xml
<BookStore>
<Book>
<Name></Name>
<Author></Author>
<Price></Price>
</Book>
<Book>
<Name></Name>
<Author></Author>
<Price></Price>
</Book>
</BookStore>
From
List<XElement> Book= xdoc.XPathSelectElements("s0:Name| s0:Author| s0:Price", namespaceManager).ToList();
I am struck in the following place :
XNamespace s0 = "urn:service.Bookstore.com";
XElement root=new XElement(s0 + "BookStore",
new XElement("Book",Book,
);
XDocument result = new XDocument(root);
But this gives the xml structure to be
<BookStore>
<Book>
<Name></Name>
<Author></Author>
<Price></Price>
<Name></Name>
<Author></Author>
<Price></Price>
</Book>
</BookStore>
Please help me in getting the expected output.Since the base xml structure looks like this
<BookStore>
<Book>
<Name></Name>
<Author></Author>
<Price></Price>
<Name></Name>
<Author></Author>
<Price></Price>
</Book>
</BookStore>
But I want it as two separate instances of
It sounds like you basically need to take the list of elements and group them into groups of 3 elements, putting each group in a Book element:
// The name/author/price elements you're already getting
var elements = ...;
var groups = elements.Select((value, index) => new { value, index })
.GroupBy(pair => pair.index / 3, pair => pair.value);
XNamespace s0 = "urn:service.Bookstore.com";
XDocument result = new XDocument(new XElement(s0 + "BookStore",
groups.Select(g => new XElement("Book", g))));
Try It:
XElement xElement = new XElement("BookStore", new XElement("Book", new XElement("Name", "value"), new XElement("Author", "value"), new XElement("Price", "value")));
xElement.Save("Location.xml");

Lambda linq repeated information

I have the next code that i developed myself. It works, but if in the XML has 3 records, it will show the three records, but all of them will have the same information that the last one has.
//Load file and puts it on a IEnumerable interface
IEnumerable<MObject> MObjects = XDocument.Load(v_urlDataConnection)
.Element("MTestData").Descendants("book")
.Select(x => new MObject
{
Title = x.Element("title").Value,
Artist = x.Element("artist").Value,
Company = x.Element("company").Value,
Country = x.Element("country").Value,
Year = x.Element("year").Value,
Price = float.Parse(x.Element("price").Value)
}).ToList();
The xml is:
<MTestData>
<book>
<title>Scenes</title>
<artist>Dream Theater</artist>
<company>Vertigo</company>
<country>USA</country>
<year>1999</year>
<price>19.99</price>
</book>
<book>
<title>Falling</title>
<artist>Dream Theater</artist>
<company>3</company>
<country>3</country>
<year>3</year>
<price>3</price>
</book>
<book>
<title>Images and Words</title>
<artist>Dream Theater</artist>
<company>Elektra</company>
<country>USA</country>
<year>1991</year>
<price>15</price>
</book>
</MTestData>

Get XML content from XmlNodeList

I have a question that may seem very simple, but it's giving me a headache. I have this XML file that has multiple entries, like:
<books>
<book>
<id>1</id>
<firstCover>
<author name="**" age="**" />
<title name="zz" font="yyy" size="uuu"/>
</firstCover>
<lastCover>
</lastCover>
</book>
<book>
<id>2</id>
<firstCover>
<author name="**" age="**" />
<title name="zz" font="yyy" size="uuu"/>
</firstCover>
<lastCover>
</lastCover>
</book>
</books>
Now, in order to get the XML content for first cover of book with id=1, I do this:
XmlNodeList b = root.SelectNodes("/books/book[contains(id,1)]/firstCover");
Then I would really need to take the whole content of what's inside the firstCover for that book :
<author name="**" age="**" />
<title name="zz" font="yyy" size="uuu"/>
and insert it into an XmlElement. This is where I'm stucked. I know I can do it with a foreach loop in XmlNodeList, but is there a more simple way?
I'm guessing you want to actually insert it into an XMLElement in another XMLDocument.
Is this what you are looking for?
XmlDocument sourceDoc = new XmlDocument();
//This is loading the XML you present in your Question.
sourceDoc.LoadXml(xmlcopier.Properties.Resources.data);
XmlElement root = sourceDoc.DocumentElement;
XmlElement b = (XmlElement)root.SelectSingleNode("/books/book[contains(id,1)]/firstCover");
XmlDocument destDoc = new XmlDocument();
XmlElement destRoot = destDoc.CreateElement("base");
destDoc.AppendChild(destRoot);
XmlElement result = destDoc.CreateElement("firstCover");
result.InnerXml = b.InnerXml;
destRoot.AppendChild(result);
destDoc.Save("c:\\test.xml");

Categories

Resources