Writing To Existing XML FILE - c#

I have a xml file, that looks something like this:
<?xml version="1.0" encoding="utf-8"?>
<Settings>
<WhereDoCopy Path="C:\Users\USER\Desktop\jobs" />
</Settings>
What can I do, to add an Element to that file?

XDocument doc = XDocument.Load("your.xml");
XElement item = new XElement(WhereDoCopy ,
new XAttribute("Path", "C:\Users\USER\Desktop\jobs2"));
doc.Root.Add(item);
http://msdn.microsoft.com/en-us/library/system.xml.linq.xdocument.aspx

Related

How to add xsi:noNamespaceSchemaLocation to Serializer

I build an XML Document which needs to be validated against a xsd file. Thus I need a reference to the xsd file in the root element of the xml. So far I use this C# Code:
var ser = new XmlSerializer(typeof(myspecialtype));
XmlSerializerNamespaces MainNamespace = new XmlSerializerNamespaces();
MainNamespace.Add("xlink", "http://www.w3.org/1999/xlink");
MainNamespace.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
using (XmlWriter w = XmlWriter.Create(#"C:\myxmlfile.xml"))
{
w.WriteProcessingInstruction("xml-stylesheet", "type=\"text/xsl\" href=\"utils/somexsl.xsl\"");
ser.Serialize(w, LeBigObject, HauptNs);
}
The resulting Xml begins like this:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="utils/somexsl.xsl"?>
<caddy-xml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlVersion="03.07.00">
but I need this:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="utils/somexsl.xsl"?>
<caddy-xml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlVersion="03.07.00" xsi:noNamespaceSchemaLocation="utils/theveryimportant.xsd">
I came across "CreateAttribute" here: Add Namespace to an xml root node c# but I can't put it together with the Serializer. Thank you!
I was pointed to the solution here:
https://social.msdn.microsoft.com/Forums/en-US/e43585c6-181b-4449-8806-b07f82681a2a/how-to-include-xsinonamespaceschemalocation-in-the-xml?forum=asmxandxml
I added this to my class:
[XmlAttribute("noNamespaceSchemaLocation", Namespace = XmlSchema.InstanceNamespace)]
public string attr = "utils/theveryimportant.xsd";
and it works.

How to edit content of a tag in a xml file

Example
<?xml version="1.0" encoding="UTF-8"?>
<Settings>
<Tag1>XXXX</Tag1>
<Tag2>YYYY</Tag2>
<Tag3>true</Tag3>
<Tag4>ZZZZ</Tag4>
</Settings>
I want to edit only the contents of Tag3 without having to create another .xml file
You may edit your XML file like this:
XmlDocument doc = new XmlDocument();
doc.Load("D:\\somefile.xml");
XmlNode root = doc.DocumentElement;
XmlNode myNode = root.SelectSingleNode("Settings::Tag3");
myNode.Value = "blabla";
doc.Save("D:\\somefile.xml");

Issue on saving the XML file after editing it

I have an XML file with some data on it..for example
<?xml version="1.0" encoding="utf-8"?>
<CreateAndSendMessageRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.communisis.com/lv">
<CompositionRequest>
<Metadata xmlns="http://lv.com/gi/si/common/CommonTypes">
<PolicyReference>250028766505DN</PolicyReference>
<AccountReference>Test1234</AccountReference>
<QuoteReference>Test3214</QuoteReference>
<OutboundTransactionID>string</OutboundTransactionID>
</Metadata>
Now i want to replace POLICY REFERENCE value with some dummy data. I am able to do that but now i have to save it as a new file with a different file name..
How can i achieve that..
For reference i am giving my code.
XmlDocument doc = new XmlDocument();
doc.Load(filepath);
XmlNodeList node = doc.GetElementsByTagName("PolicyReference");
var item =node.Item(0);
string value = item.FirstChild.Value;
string nevalue = value.Replace(value, "Test123");
doc.DocumentElement.;
doc.Save(#"C:\Test\file.xml");
The xml wasn't valid.
Anyway, this is how to make it work:
Xml file:
<?xml version="1.0" encoding="UTF-8"?>
<CreateAndSendMessageRequest>
<CompositionRequest>
<Metadata xmlns="http://lv.com/gi/si/common/CommonTypes">
<PolicyReference>250028766505DN</PolicyReference>
<AccountReference>Test1234</AccountReference>
<QuoteReference>Test3214</QuoteReference>
<OutboundTransactionID>string</OutboundTransactionID>
</Metadata>
</CompositionRequest>
</CreateAndSendMessageRequest>
Code:
XmlDocument doc = new XmlDocument();
doc.Load("bho.xml");
XmlNodeList node = doc.GetElementsByTagName("PolicyReference");
node[0].InnerText = "Test123";
doc.Save("file.xml");
Result xml:
<?xml version="1.0" encoding="UTF-8"?>
<CreateAndSendMessageRequest>
<CompositionRequest>
<Metadata xmlns="http://lv.com/gi/si/common/CommonTypes">
<PolicyReference>Test123</PolicyReference>
<AccountReference>Test1234</AccountReference>
<QuoteReference>Test3214</QuoteReference>
<OutboundTransactionID>string</OutboundTransactionID>
</Metadata>
</CompositionRequest>
</CreateAndSendMessageRequest>
Hope it helps you ^^

Update an xml file in a storage folder by adding nodes using C#

I'm making a universal app in C# and I'm trying to update an xml file in the storage folder by adding some nodes to it. Ideally, starting with a file like this
<?xml version="1.0" encoding="UTF-8"?>
<MyRoot>
<ParentNode>
<myNode1>value1</myNode1>
<myNode2>value2</myNode2>
</ParentNode>
</MyRoot>
I would like to add other nodes in order to obtain
<?xml version="1.0" encoding="UTF-8"?>
<MyRoot>
<ParentNode>
<myNode1>value1</myNode1>
<myNode2>value2</myNode2>
</ParentNode>
<ParentNode>
<myNode1>value3</myNode1>
<myNode2>value4</myNode2>
</ParentNode>
</MyRoot>
What I obtain instead is an invalid xml file with the content I want appended to the previous content like this
<?xml version="1.0" encoding="UTF-8"?>
<MyRoot>
<ParentNode>
<myNode1>value1</myNode1>
<myNode2>value2</myNode2>
</ParentNode>
</MyRoot><?xml version="1.0" encoding="utf-8"?>
<MyRoot>
<ParentNode>
<myNode1>value1</myNode1>
<myNode2>value2</myNode2>
</ParentNode>
<ParentNode>
<myNode1>value3</myNode1>
<myNode2>value4</myNode2>
</ParentNode>
</MyRoot>
Here is the code
StorageFile myFile = await ApplicationData.Current.LocalFolder.GetFileAsync("myFile.xml");
using (IRandomAccessStream writeStream = await myFile.OpenAsync(FileAccessMode.ReadWrite))
{
// convert IRandomAccessStream to IO.Stream
Stream s = writeStream.AsStreamForWrite();
//xml
XDocument document = XDocument.Load(s);
document.Root.Add(
new XElement("ParentNode",
new XElement("myNode1", "value3"),
new XElement("myNode2", "value4"))
);
document.Save(s);
}
After your call to XDocument.Load you are positioned at the end of the stream, so the call to document.Save will append the new contents at the end of the stream.
As long as you're only adding nodes to the existing XML making the file longer with every save, you could resolve the issue by moving to the beginning of the stream, before calling document.Save:
document.Root.Add(
new XElement("ParentNode",
new XElement("myNode1", "value3"),
new XElement("myNode2", "value4"))
);
s.Seek(0, SeekOrigin.Begin); // <-- add this line
document.Save(s);
If you start removing nodes, this won't work because not all of the old file will be overwritten and some remains will stay at the end. In this case you will need to close the stream after loading it and create a new file for saving by overwriting the existing one:
StorageFile newFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("myFile.xml",
CreationCollisionOption.ReplaceExisting);
Try something along the lines of:
XmlDocument doc = new XmlDocument();
doc.Load("yourfile.xml");
var root = doc.DocumentElement;
var parentNode = doc.CreateElement("ParentNode");
root.AppendChild(parentNode);
var myNode1 = doc.CreateElement("myNode1");
myNode1.Value = "value3";
parentNode.AppendChild(myNode1);
// ...add more nodes etc...
doc.Save("yourfile.xml");

How to write an xml attribute without replace all attributes?

I'm using this:
public void WriteSettings(string key, string value)
{
XmlWriterSettings xmlSettings = new XmlWriterSettings();
xmlSettings.Indent = true;
xmlSettings.NewLineOnAttributes = true;
XmlWriter writer = XmlWriter.Create(TMP_FULLPATH, xmlSettings);
writer.WriteStartElement("settings");
writer.WriteAttributeString(key, value);
writer.WriteEndAttribute();
writer.WriteEndDocument();
writer.Flush();
writer.Close();
}
But any modification replaces all attributes with only the last remaining attribute that I am trying to add. For example:
current XML:
<?xml version="1.0" encoding="utf-8"?>
<settings TitleFormat="name:%name% date:%date%" />
when I do:
WriteSettings("foo", "baa");
the XML is:
<?xml version="1.0" encoding="utf-8"?>
<settings foo="baa" />
instead of:
<?xml version="1.0" encoding="utf-8"?>
<settings TitleFormat="name:%name% date:%date%" foo="baa" />
How can I fix that?
You are writing a new file, with no consideration at all of the old. To update a document, you must load it into a DOM, edit the DOM, and save the DOM:
var doc = new XmlDocument();
doc.Load(path);
doc.DocumentElement.SetAttribute(key, value);
doc.Save(path);
you are creating new file each time you call XmlWriter.Create(), do something like this.

Categories