Writing XML for dataset containing multiple tables - c#

I'm getting 2 tables in my dataset.
I need to structure my XML as:
<MyRoot>
<Settings>
<Param1>value1</Param1>
<Param2>value2</Param2>
<Param3>value3</Param3>
</Settings>
<Books>
<Book>
<BookId>1000</BookId>
<BookName>Book1</BookName>
</Book>
<Book>
<BookId>2000</BookId>
<BookName>Book2</BookName>
</Book>
</Books>
</MyRoot>
But when I use datSet.WriteXML(); I'm getting XML as:
<MyRoot>
<Settings>
<Param1>value1</Param1>
<Param2>value2</Param2>
<Param3>value3</Param3>
</Settings>
<Book>
<BookId>1000</BookId>
<BookName>Book1</BookName>
</Book>
<Book>
<BookId>2000</BookId>
<BookName>Book2</BookName>
</Book>
</MyRoot>
So, I'm not able to add separate dataset name as "Books" to second table (dataSet.Tables[1]). Is there any way that I can do that?
I tried the below code:
dataSet = GetList();
dataSet.DataSetName = "MyRoot";
dataSet.Tables[0].TableName = "Settings";
dataSet.Tables[1].TableName = "Books";
StringWriter swriter = new StringWriter();
dataSet.WriteXml(swriter);
string dsResult = swriter.ToString();
Thanks.

I don't know a way to tell DataSet.WriteXml directly to write the XML in the way you want it, so you have two big options:
Let DataSet.WriteXml write the XML and modify it afterwards.
Write the serialization code yourself.
For both ways you have different options how to do it. In the first case you can
Load the created XML into a XDocument or XmlDocument and restructure it via code.
Transform your XML via XSLT (I would prefer that over the code solution)
The options in the second case should be obvious. If you create your own XmlWriter and use DataTable.WriteXml to write to it, you should be able to define your own format in a few lines of code.
To choose the right solution for your use case is up to you. I would probably go for the XSTL solution.

You can overwrite the original XML by some code like below.
string filename = "XmlDoc.xml";
System.IO.FileStream stream = new System.IO.FileStream (filename, System.IO.FileMode.Create);
ds.WriteXml(stream);
XmlDocument xmldoc = new XmlDocument("XmlDoc.xml");
XmlNode node1 = xmldoc.CreateNode("Books","Books");
foreach(XmlNode nd in xmldoc.Nodes) {
if(node.value =="Book")
node1.AppendChild(nd);
}
xmldoc.Nodes.Add(node1);
xmldoc.SaveAs("newXmlDoc.Xml");

Related

find if a code exists in xml, using c#

I am starting to work with xml and I am trying to know if there is a way to search a code in this.
Here you are my xml
<?xml version="1.0" encoding="UTF-8"?>
<doctors_hospital>
<doctor>
<code>1757D</code>
<name>one</name>
</doctor>
<doctor>
<code>1169L</code>
<name>two</name>
</doctor>
... continues xml
</doctors_hospital>
I want to look for the code "aab" using c#, and this is my code..
var document =new XmlDocument();
document.Load("O:\\test\\doctor.xml");
XmlNode doctor;
XmlNode root = document.DocumentElement;
doctor = root.SelectSingleNode("/doctors_hospital/doctor/code='aab'");
I can not do this. any suggestion? thanks
Assuming SelectingSingleNode takes a standard XPath expression, what you want to use is
/doctors_hospital/doctor[code='aab']
This will select the entire doctor node with the matching code value.
I agree with Jim, alternatively you could also use Linq to Xml and do this.
XDocument doc = XDocument.Load(filepath);
var codeExist = doc.Descendants("code").Any(x=>(string)x.Value == "1169L");
Check this Demo

Write xml from textbox to existing xml file without replacing old text, just adding new

So... I have 2 textboxes and 1 button.
And when I input data to those textboxes, and click the button, I would like it to enter xml file and add new element with attributes to it, without replacing it.
After a lot of browsing I managed to do something that replaced all text in my xml file, or I got an error, so I decided to post a question here.
So this is how my xml file looks:
<library>
<book name="Her way" price="20"></book>
<book name="His way" price="20"></book>
</library>
and what I'm trying to do is to insert:
<book name="Their way" price="22"></book>
bellow last one so it would look like:
<library>
<book name="Her way" price="20"></book>
<book name="His way" price="20"></book>
<book name="Their way" price="22"></book>
</library>
And every time I click button again, it adds it same way, ofc I would change name and price in textbox.
I came up with this code, but I am fairly new to xml so I don't know how to modify it or make it work.
XDocument doc = XDocument.Load("booklibrary.xml");
doc.Add(new XElement("book",
new XAttribute("name", textBox1.Text),
new XAttribute("price", textBox3.Text)));
doc.Save("booklibrary.xml");
Thank you!
Don't use XDocument if you aren't working with namespaces. Just use an XElement and your code will work:
var library = XElement.Load("booklibrary.xml");
library.Add(new XElement("book",
new XAttribute("name", textBox1.Text),
new XAttribute("price", textBox3.Text)));
library.Save("booklibrary.xml");
Because you used XDocument, Add tried to add the new element next to the root element <library> instead of inside it, causing an exception because there can be only one root element. Several illustrative examples can be found on MSDN.
By using XElement as shown above, this problem is fixed.
I would use LINQ to XML instead, very easy to use and tons of functionality!:
XElement ele = XElement.Load("booklibrary.xml");
ele.Element("library").Add(
new XElement("book",
new XAttribute("name", textBox1.Text),
new XAttribute("price", textBox3.Text)));
ele.Save();
This is much cleaner, and it uses the new .NET stuff.

how Deserializing this type of xml file?

<row>
<id>1</id>
<code></code>
<name></name>
<address></address>
<state></state>
<zone>?</zone>
</row>
<row>
<id>2</id>
<code>AA</code>
<name>Ataria</name>
<address>Sitapur National Highway 24, Uttar Pradesh</address>
<state>Uttar Pradesh</state>
<zone>NER</zone>
</row>
i have no root element in this xml file only row element start and end this xml file.
how Deserializing this type of data ? in c#
If you sure that missing root is only the one issue with your XML - just add it manually:
string fileContent = File.ReadAllText(path);
string rawXml = "<root>" + fileContent + "</root>";
// now you can use LINQ-to-XML or whatever
XDocument xdoc = XDocument.Load(rawXml);
You can also load an XML Fragment directly, via
XmlReaderSettings settings = new XmlReaderSettings();
settings.ConformanceLevel = ConformanceLevel.Fragment;
using (XmlReader reader = XmlReader.Create("tracelog.xml", settings))
{
while (reader.Read())
{
// Process each node of the fragment,
// possibly using reader.ReadSubtree()
}
}
You would create XElements by passing the results of reader.ReadSubTree() to XElement.Load(...).
Well to start with, it's not an XML file - or at least, it doesn't represent an XML document.
One option would be to copy the file into a new file which does have document start/end tags... then you can load it as a normal document. Just create a file, write a document start tag, copy the contents of this file, then write a document end tag, and close the file handle. You could even do this in memory.
Alternatively, it may be possible to read it as it is, in fragments - possibly via XmlReader. I can't say it's something I've done, and I'd generally encourage you to create a full XML file instead, as then you'll be on more familiar territory.
its not an XML file if it doesn't have the root. parser will throw an error if you try to parse it. you can do this way
<?xml version="1.0"?>
<Root>
--- add your file content here
</Root>
then give this file path to the parser.

How to flat xml to one line in c# code?

How to flat xml to one line in c# code ?
Before:
<CATALOG>
<CD>
<TITLE>Empire Burlesque</TITLE>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1985</YEAR>
</CD>
</CATALOG>
After:
<CATALOG><CD><TITLE>Empire Burlesque</TITLE><ARTIST>Bob Dylan</ARTIST>COUNTRY>USA</COUNTRY>....
Assuming you're able to use LINQ to XML, and the XML is currently in a file:
XDocument document = XDocument.Load("test.xml");
document.Save("test2.xml", SaveOptions.DisableFormatting);
If you cant use LINQ to XML, you can:
XmlDocument xmlDoc = new XmlDocument()
xmlDoc.LoadXml("Xml as string"); or xmlDoc.Load(filepath)
xmlDoc.InnerXml -- this should return one liner
If you have the XML in a string:
xml.Replace("\n", "").Replace("\r", "")
I know, that this is old question, but it helped me to find XDocument.ToString()
XDocument doc = XDocument.Load("file.xml");
// Flat one line XML
string s = doc.ToString(SaveOptions.DisableFormatting);
Check SaveOptions documentaion
Depends what you are working with and what output you need...
John Skeet's answer works if reading and writing to files.
Aleksej Vasinov's answer works if you want xml without the xml declaration.
If you simply want the xml in a string, but want the entire structure of the xml, including the declaration, ie..
<?xml version "1.0" encoding="utf-16"?> <-- This is the declaration ->
<TheRestOfTheXml />
.. use a StringWriter...
XDocument doc = GetTheXml(); // op's xml
var wr = new StringWriter();
doc.Save(wr, SaveOptions.DisableFormatting);
var s = wr.GetStringBuilder().ToString();

How can I correct the code to read a xml file?

This code works as it is but when I reference an external xml file in doc.Loadxml, it stops working. How can I get it to work? I don't quite understand.
I use this to call GetXmlData and provide source for the gridview :GridView1.ItemsSource = GetXmlData();
private static object GetXmlData()
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(#"<?xml version=""1.0"" encoding=""utf-8"" ?>
<Products>
<Product>
<ID>1</ID>
<Name>ASP.NET</Name>
</Product>
</Products>
");
XmlDataProvider provider = new XmlDataProvider();
provider.IsAsynchronous = false;
provider.Document = doc;
provider.XPath = "Products/Product";
return new ObservableCollection<XmlNode>((IEnumerable<XmlNode>)provider.Data);
}
You need
doc.Load(fileName);
instead of
doc.LoadXml(xml);
XMLDocument has several Load methods, see them with their description:
Load(Stream) Loads the XML document from the specified stream.
Load(String) Loads the XML document from the specified URL.
Load(TextReader) Loads the XML document from the specified TextReader.
Load(XmlReader) Loads the XML document from the specified XmlReader.
LoadXml(string) Loads the XML document from the specified string.
You're using the last one which is as described used to load XML from a string.
Since you need to load the XML from a file, so you've to use to Load method, as opposed to LoadXml. I think second method is better suited for your situation. You can pass the fullpath of the XML file.
This should help you:
XmlDocument doc = new XmlDocument();
doc.Load(file_path);
The method you are calling only loads xml from a string. You need to read it from a file which requires a different method.

Categories