Load an XML and add a node to it - c#

What I am trying to do is when I press a button, I load an XML file and try to add nodes to it.
XmlDocument doc = new XmlDocument();
doc.Load("XMLFILE.xml");
XmlNode Tag1 = doc.CreateElement("Tag1");
XmlNode Tag2 = doc.CreateElement("Tag2");
Tag2.InnerText = food.Text;
Tag1.AppendChild(Tag2);
XmlNode Tag3 = doc.CreateElement("Tag3");
Tag3.InnerText = games.Text;
Tag1.AppendChild(Tag3);
XmlNode Tag4 = doc.CreateElement("Tag4");
Tag4.InnerText = life.Text;
Tag1.AppendChild(Tag4);
When I run the code and click the button the file is empty and only has 1 tag which is one I made when I first created the file. So how can I load an XML and add to it?

There are two issues with the code you posted:
You created a bunch of XML nodes but I don't see anywhere that you actually add them to the document you loaded. You need to call AppendChild() on the DocumentElement or some other node that's already in the file if you want your new nodes to appear in the XML tree.
Your code is loading an XML document from disk into memory and editing it, but you are never storing the XML document back to disk again. You need to call Save() on the updated document if you want to see the changes persisted back to your file.

Related

Modify xml with Xmldocument in C#

I am trying to edit the values of an xml document following the instructions found on another post here How to modify existing XML file with XmlDocument and XmlNode in C# .
here is my code
XmlDocument xml = new XmlDocument();
xml = xml.Load(#"https://www.aade.gr/sites/default/files/2020-09/SampleXML_1.1%20%20%28%CE%A4%CE%99%CE%9C-%CE%A0%CE%A9%CE%9B%CE%97%CE%A3%CE%97%CE%A3_%CE%91%CE%A5%CE%A4%CE%9F%CE%A4%CE%99%CE%9C%29%20.xml");
XmlNodeList aNodes = xml.SelectNodes("/InvoicesDoc/invoice/issuer/vatNumber");
foreach (XmlNode aNode in aNodes)
{
XmlAttribute vatAttribute = aNode.Attributes["vatNumber"];
vatAttribute.Value = "123456789";
}
xml.Save(#"C:\Users\Kostas\Desktop\mydata\infinal.xml");
My problem is that XmlNodeList aNodes will return empty; i have tried to change the xml.SelectNodes("/InvoicesDoc/invoice/issuer/vatNumber") to xml.SelectNodes("/InvoicesDoc/invoice/issuer") and all the way up to single xml.SelectNodes("/InvoicesDoc") but still XmlNodeList aNodes will return empty.
First attempts i loaded the XML doc from file and had the issue. Then i thought maybe something wrong with the file so changed the load of the file directly from the site provides this xml template i need to work on. Both options will load the file fine as i can see it when is saved but my changes will not complete since aNodes is empty and foreach loop will skip straight away.
What am i doing wrong?
thanks for your help in advance.
ps this is the xml i need to edit
https://www.aade.gr/sites/default/files/2020-09/SampleXML_1.1%20%20%28%CE%A4%CE%99%CE%9C-%CE%A0%CE%A9%CE%9B%CE%97%CE%A3%CE%97%CE%A3_%CE%91%CE%A5%CE%A4%CE%9F%CE%A4%CE%99%CE%9C%29%20.xml
Update: I just tried with another xlm found in microsoft example called books on https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms762271(v=vs.85)
XmlNodelist will also return null/empty when i look for /catalog/book . So the good side is that there is no problem with original xml file i need to edit and the bad side is that still i cannot figure out what i am doing wrong.
XmlNodeList aNodes returns null because the xml contains these namespace declarations:
<InvoicesDoc xmlns=\"http://www.aade.gr/myDATA/invoice/v1.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
xsi:schemaLocation=\"http://www.aade.gr/myDATA/invoice/v1.0/InvoicesDoc-v0.6.xsd\"
xmlns:icls=\"https://www.aade.gr/myDATA/incomeClassificaton/v1.0\"
xmlns:ecls=\"https://www.aade.gr/myDATA/expensesClassificaton/v1.0\">
You need to manage your xml doing something like this:
XmlDocument xml = new XmlDocument();
xml.Load(#"https://www.aade.gr/sites/default/files/2020-09/SampleXML_1.1%20%20%28%CE%A4%CE%99%CE%9C-%CE%A0%CE%A9%CE%9B%CE%97%CE%A3%CE%97%CE%A3_%CE%91%CE%A5%CE%A4%CE%9F%CE%A4%CE%99%CE%9C%29%20.xml");
XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);
manager.AddNamespace("InvoicesDoc", "http://www.aade.gr/myDATA/invoice/v1.0");
//Example to get the root element
XmlNodeList root = xml.SelectNodes("/InvoicesDoc:InvoicesDoc", manager);
//Example to get the VatNumber tag
XmlNodeList aNodes =xml.SelectNodes("/InvoicesDoc:InvoicesDoc/InvoicesDoc:invoice/InvoicesDoc:issuer/InvoicesDoc:vatNumber", manager);

Xamarin Forms files do not carry over between uses

I've been trying to save an xml file to the phone for later use. I have tried to save it to Environment.SpecialFolder.MyDocuments, Environment.SpecialFolder.Personal, and Environment.SpecialFolder.LocalApplicationData. All of these work in the app session, as in I can save a file and read from it as long as the app is running. As soon as I close the app and reopen it, the app is supposed to read from the file and display information, but for some reason the file either does not exist (in which case the app creates a new blank one), or it's blank. I want to try and see what the file looks like itself, but I can't even find where it's stored because I just use the Environment.SpecialFolder... path. I've so far only tested this app on android if that helps.
Any help is greatly appreciated!
Here is the code to save data to the file checkins.xml:
//make new check in
//load the document
XmlDocument checkInDoc = new XmlDocument();
checkInDoc.Load(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "checkIns.xml");
//create the nodes
XmlNode checkInNode = checkInDoc.CreateElement("CheckIn");
XmlNode nameNode = checkInDoc.CreateElement("Name");
XmlNode timeNode = checkInDoc.CreateElement("Time");
//assign values to the nodes
nameNode.InnerText = "New Check In";
timeNode.InnerText = "9:00 PM";
//place nodes in document and save
checkInNode.AppendChild(nameNode);
checkInNode.AppendChild(timeNode);
checkInDoc.DocumentElement.AppendChild(checkInNode);
checkInDoc.Save(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "checkIns.xml");
And here is the code used to load the checkins from that file to a list:
List<CheckIn> tempList = new List<CheckIn>();
//Load Checkins from file into checkInList
XmlDocument checkInDoc = new XmlDocument();
checkInDoc.Load(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "checkIns.xml");
foreach(XmlNode node in checkInDoc.SelectNodes("CheckIns/CheckIn"))
{
tempList.Add(new CheckIn() { Name = node.SelectSingleNode("Name").InnerText, Time = node.SelectSingleNode("Time").InnerText });
}
I've actually solved this an entirely different way. I couldn't get saving/loading the file to work so I was able to use Application.Current.Properties which holds basic key/value pairs and is persistent between uses. I would highly recommend using this as it has worked perfectly for me.

XDocument Add multiple XElements

In my Windows Phone 8 C#/XAML .NET 4.5 Project, I'm trying to create an XDocument with similar structure:
<element1>
<subelement1>
</subelement1>
<subelement2>
...etc...
</subelement2>
</element1>
<element2>
<subelement1>
</subelement1>
<subelement2>
...etc...
</subelement2>
</element2>
The method creating the document looks like (simplified for the question purposes):
... createXML()
{
XDocument doc = new XDocument();
XElement elem1 = new XElement("element1");
elem1.Add(new XElement("subelement1"));
XElement elem2 = new XElement("element2");
doc.Add(elem1);
doc.Add(elem2);
}
But I keep getting InvalidOperationException saying that it would create a invalid document structure.
I know why - it would cause the document to have multiple "root nodes" - but I effectively need it that way.
This structure is needed for webservice done by third party, which recieves the document as a string.
So the question is "How to achieve this structure? Should I use some other XObject instead?"
(I know that probably the most simple solution would be to use collection of XElements...just askin' if there is another way out of curiosity)
The structure that you specified at the top of the post is illegal, because valid XML documents must have a single root element; your document has two elements at the top level, which is not allowed.
You can solve this problem by adding a root element at creation time, and then discarding it when reading the document;
document = new XDocument(new XElement("root", elem1, elem2));

How to change the data within elements in a XML file using C#?

I'm kind of new to XML files in C# ASP.NET. I have a XML in the below format:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Installation>
<ServerIP>192.168.20.110</ServerIP>
<DB_Name>USTCKT1</DB_Name>
<Username>jorame</Username>
<Password>Cru$%e20</Password>
<Table_PreFix>TCK</Table_PreFix>
</Installation>
I need to change the values within each element. For example, when an user clicks I should be able to replace 192.168.20.110 with 192.168.1.12.
How can I accomplish this? Any help will be really appreciated.
You should look at using the methods in the XDocument class. http://msdn.microsoft.com/en-us/library/bb301598.aspx
Specifically look at the methods: Load(string) - to load an XML file, Element() - to access a specific element and Save(string) - to save the XML document. The page on Element() has some sample code which can help.
http://msdn.microsoft.com/en-us/library/system.xml.linq.xcontainer.element.aspx
You can do something like this using the XDocument class:
XDocument doc = XDocument.Load(file.xml);
doc.Element("Installation").Element("ServerIP").Value = "192.168.1.12";
//Update the rest of the elements
doc.Save(file.xml);
More Details
If you run into namespace issues when selecting your elements you will need to include the xml namespace in the XElement selectors eg doc.Element(namspace + "Installation")
In general, you can do it in the following steps:
Create a new XmlDocument object and load the content. The content might be a file or string.
Find the element that you want to modify. If the structure of your xml file is too complex, you can use xpath you find what you want.
Apply your modification to that element.
Update your xml file.
Here is a simple demo:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("file.xml"); // use LoadXml(string xml) to load xml string
string path = "/Installation/ServerIP";
XmlNode node = xmlDoc.SelectSingleNode(path); // use xpath to find a node
node.InnerText = "192.168.1.12"; // update node, replace the inner text
xmlDoc.Save("file.xml"); // save updated content
Hope it's helpful.

Replacing the innertext of an Xml node/element

First of all this is C#. I am creating a internet dashboard for a small group of colleages in the NHS.
Below is an example xml file in which I need to change the innertext of. I need to replace a specific element for example "Workshop1." Because we have a few workshops I cannot afford to use a general writer because it will replace all the information on the XML document with this one bit of code below.
<?xml version="1.0" ?>
<buttons>
<workshop1>hello</workshop1>
<url1>www.google.co.uk</url1>
I am using a switch case to select a specific workshop where you can change the name and add a URL of the workshop and using this code below will replace the whole document.
public void XMLW()
{
XmlTextReader reader = new XmlTextReader("C:\\myXmFile.xml");
XmlDocument doc = new XmlDocument();
switch (comboBox1.Text)
{
case "button1":
doc.Load(reader); //Assuming reader is your XmlReader
doc.SelectSingleNode("buttons/workshop1").InnerText = textBox1.Text;
reader.Close();
doc.Save(#"C:\myXmFile.xml");
break;
}
}
So just to clarify I want my C# program to search through the XML document find the element "Workshop1" and replace the innertext with text from a textBox. and be able to save it without replacing the whole document with one node. Thanks for looking.
Using XmlDocument and XPath you can do this
XmlDocument doc = new XmlDocument();
doc.Load(reader); //Assuming reader is your XmlReader
doc.SelectSingleNode("buttons/workshop1").InnerText = "new text";
You can use doc.Save to save the file also.
Read more about XmlDocument on MSDN.
EDIT
To save the document do this
doc.Save(#"C:\myXmFile.xml"); //This will save the changes to the file.
Hope this helps you.

Categories