Create blank XML File and then Append to it - c#

I am writing a windows forms program in C# and I want to be able to save information to an XML file.
When I first create the XML file, I just want to be able to ad the declaration
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
and then the root node which I want called "Contacts".
The final file should look like:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Contacts>
<Contact>
<Name>name</Name>
<Address>address</Address>
<Contact>
<Contacts>
There will be multiple <Contact></Contact> elements.
The problem I am having is when I first create the XML file.
My XML operations are in their own class.
This is the method to create the file:
public void createFile()
{
if (!File.Exists(fileName))
{
//Populate with data here if necessary, then save to make sure it exists
xmlFile = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XComment("XML File for storing " + RootName));
xmlFile.Save(FileName);
}
}
When I try to run this, I get an ArgumentNullException was unhandled error.
Any ideas how to actually get the data in the file and have it save?
Thanks

You'll need a root element in the file:
xmlFile.Add( new XElement( "Contacts" ) );
Although the error you are getting suggests something else is going on. Perhaps Filename is null?

Related

XML Tag / Prolog Missing

i am reading and serializing a xml file. I then make some changes to the serialized xml data and save again back to a new file. The serializing and deserializing, saving to file is all working, however I have a value at the top of the xml file that is missing.
How do I set this value before saving the xml file?
Original XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?>
New File XML (missing )
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
It is very simple to implement via LINQ to XML API.
c#
void Main()
{
XDocument xdoc = XDocument.Parse("<root><el>123</el></root>"); // or .Load()
xdoc.Declaration = new XDeclaration("1.0", "UTF-8", "false");
xdoc.Save(#"e:\temp\Output.xml");
}

C# Skip anything to next tag

I have a log file in xml format like
<log> // skip this node
<?xml version="1.0" encoding="UTF-8"?>
<qbean logger="main-logger">
</qbean>
</log>
<log> // go to this node
</log>
Now ReadToNextSibling("log") throw an exception an I need to skip content of first "log" tag and move to next "log" tag without throwing exception.
Is there a way?
Hint:
Your XML is invalid since the <?xml version="1.0" encoding="UTF-8"?> has to be before the root element. You can search for it and remove it if that fixes your problem. You can use yourXml.Repalce("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "")
You have to create a root element for your XML to be valid for parsing.
Then, you can use the XmlDocument class to parse the XML data that you have and skip anything you want. You would need something like this:
var document = new XmlDocument();
document.LoadXml(yourXml);
document.DocumentElement.ChildNodes[1]

Saving an xml file using stream results in a duplicate root elements

So I'm attempting to open an xml file, add an XElement to the root element, and save it. Except my C# Code:
StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync("UserPinouts.tpack", CreationCollisionOption.OpenIfExists);
using (var stream = await file.OpenStreamForWriteAsync())
{
XDocument doc = XDocument.Load(stream);
doc.Root.Add(new XElement(XElement.Parse(CurrentPinOut)));
doc.Save(stream);
Debug.WriteLine(doc.ToString());
stream.Flush();
}
Gives me the following xml file:
<?xml version="1.0" encoding="utf-8" ?>
<RootElement>
<XElement1/>
</RootElement>
<?xml version="1.0" encoding="utf-8" ?>
<RootElement>
<XElement1/>
<XElement2/>
</RootElement>
Instead of just that second part. I've tried changing the way I add the XElement, but I get this everytime, so I'm guessing it must be a problem with the way I open/close the stream. How could I fix this?
Try to reset stream position to the beginning, just before calling Save() method :
stream.Position = 0;
doc.Save(stream);
I have seen this solved similar problem in old Windows Phone questions. These are some of them : 1. Appending new XElement adds an entire XML to existing xml in stream, 2. updating an existing xml file in Windows Phone

export list of object to xml file in c#

I try to export a list of object(type of "Doctor") to an xml file in c#.
It compiles and runs, but the file I get isn't correct. Can someone please can tell me what I did incorrect?
the code is:
public static void exportAsXml(string fileName, List<Entity> ListOfEntity)
{
FileInfo file = new FileInfo(fileName + ".xml");
StreamWriter sw = file.AppendText();
System.Xml.Serialization.XmlSerializer writer = new System.Xml.Serialization.XmlSerializer(typeof(Doctor));
foreach (Entity e in ListOfEntity)
{
writer.Serialize(sw,e as Doctor);
}
sw.Close();
}
the xml file is:
<?xml version="1.0" encoding="utf-8"?>
<Doctor xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ID>87587579</ID>
<FirstName>Dan</FirstName>
<LastName>Adi</LastName>
<Gender>male</Gender>
<Salary>15000</Salary>
</Doctor><?xml version="1.0" encoding="utf-8"?>
<Doctor xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ID>302342246</ID>
<FirstName>Lital</FirstName>
<LastName>Gal</LastName>
<Gender>female</Gender>
<Salary>25600</Salary>
</Doctor><?xml version="1.0" encoding="utf-8"?>
<Doctor xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ID>205992457</ID>
<FirstName>Yaron</FirstName>
<LastName>Mor</LastName>
<Gender>male</Gender>
<Salary>10000</Salary>
</Doctor>
Thanks!
First of all, the resulting xml violates 2 core rules.
Xml file should have only one <?xml version="1.0" encoding="utf-8"> declaration
All your xml should be enclosed inside one root file.
In other words, in loop you generate a separate, fully-fledged xml file for each item.
Try this
var writer = new System.Xml.Serialization.XmlSerializer(typeof(List<Doctor>));
writer.Serialize(sw, ListOfEntity);
You are corrupting the xml file by serializing the doctor objects and saving it to the same file using file.AppendText();, generating corrupted xml with multiple <?xml version="1.0" encoding="utf-8"?> declarations as consequence.
You should serialize the List<Doctor> instead of serializing each doctor alone and modifying the xml file by appending text.
If you want to modify a serialized object saved inside a file, you need to deserialize the file into an object, modify it and then replace the file with the new serialized object. you cannot simply append it.

Incorrect structured XML document after deleting element

When I try to load a XML file after deleting an Element from the file, it shows the following error: Unexpected XML declaration. The XML declaration must be the first node in the document, and no white space characters are allowed to appear before it. Line 9, position 10. What is wrong with my code?
This is my XML file:
<?xml version="1.0" encoding="UTF-8"?>
<data>
<booze>booze1</booze>
<booze>booze2</booze>
<booze>booze3</booze>
<booze>booze4</booze>
</data>
And my code:
using (IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream("favorites.xml", FileMode.Open, file))
{
XDocument xDoc = XDocument.Load(stream, LoadOptions.None);
// delete node
xDoc.Descendants("data").Elements("booze").Where(x => x.Value == favorite).DescendantsAndSelf().Remove();
xDoc.Save(stream);
}
}
My guess is that when you run the code for the first time, the delete succeeds and your XDoc contains :
<?xml version="1.0" encoding="utf-8"?>
<data>
<booze>booze1</booze>
<booze>booze2</booze>
<booze>booze4</booze>
</data>
, but when calling XDoc.Save you simply append this to the favorites.xml file. After that, the favorites.xml file contains something like this:
<?xml version="1.0" encoding="UTF-8"?>
<data>
<booze>booze1</booze>
<booze>booze2</booze>
<booze>booze3</booze>
<booze>booze4</booze>
</data><?xml version="1.0" encoding="utf-8"?>
<data>
<booze>booze1</booze>
<booze>booze2</booze>
<booze>booze4</booze>
</data>
That is why all the subsequent file loads throw the error. What you should do is overwrite the file, and not append to it. The first way of doing that that comes to mind is to close the stream, open it with Mode.Truncate and then save the XDoc. Or you can delete and recreate the file. I am not that familiar with IsolatedStorageFiles so this is a wild guess.

Categories