How do I edit Node Values in an Xml File with C# - c#

I am trying to change the values in a Farming simulator 22 savegame xml file from C# in visual studio. There are a lot of nodes so I have reduced them to make things easier. I want to know how to replace the value in the node using C# with out having to create and rebuild the xml file from scratch.
the path to the xml file is: (C:\Users\Name\Documents\My Games\FarmingSimulator2022\savegame1\careerSavegame.xml)
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<careerSavegame revision="2" valid="true">
<settings>
<savegameName>My game save</savegameName>
<creationDate>2022-05-03</creationDate>
<mapId>MapFR</mapId>
<mapTitle>Haut-Beyleron</mapTitle>
<saveDateFormatted>2022-08-22</saveDateFormatted>
<saveDate>2022-08-22</saveDate>
<resetVehicles>false</resetVehicles>
</careerSavegame>

You can use the System.Xml.Linq namespace to access the xml file. This will load the file in the memory.
There is one class inside it, XDocument, that represents the xml document.
String filePath = "C:\Users\Name\Documents\My Games\FarmingSimulator2022\savegame1\careerSavegame.xml"
XDocument xdoc = XDocument.Load(filePath);
var element = xdoc.Elements("MyXmlElement").Single();
element.Value = "foo";
xdoc.Save("file.xml");
You can set the element variable as per the one which is needed to be replaced.

Through some research I found the solution to editing the values within the nodes. In this example I only change the value of savegameName, but it will be the same for the rest.
//Routing the xml file
XmlDocument xmlsettings = new XmlDocument();
xmlsettings.Load(#"D:\careerSavegame.xml");
//Setting values to nodes through innertext
String FarmNameSetting = "Martek Farm";
XmlNode savegameNamenode =
xmlsettings.SelectSingleNode
("careerSavegame/settings/savegameName");
savegameNamenode.InnerText = FarmNameSetting;

Related

C# Parsing XML in ISO-8859-1

I'm working on a tool for validating XML files grabbed from a mainframe. For reasons beyond my control every XML file is encoded in ISO 8859-1.
<?xml version="1.0" encoding="ISO 8859-1"?>
My C# application utilizes the System.XML library to parse the XML and eventually a string of a message contained within one of the child nodes.
If I manually remove the XML encoding line it works just fine. But i'd like to find a solution that doesn't require manual intervention. Are there any elegant approaches to solving this? Thanks in advance.
The exception that is thrown reads as:
System.Xml.XmlException' occurred in System.Xml.dll. System does not support 'ISO 8859-1' encoding. Line 1, position 31
My code is
XMLDocument xmlDoc = new XMLDocument();
xmlDoc.Load(//fileLocation);
As Jeroen pointed out in a comment, the encoding should be:
<?xml version="1.0" encoding="ISO-8859-1"?>
not:
<?xml version="1.0" encoding="ISO 8859-1"?>
(missing dash -).
You can use a StreamReader with an explicit encoding to read the file anyway:
using (var reader = new StreamReader("//fileLocation", Encoding.GetEncoding("ISO-8859-1")))
{
var xmlDoc = new XmlDocument();
xmlDoc.Load(reader);
// ...
}
(from answer by competent_tech in other thread I linked in an earlier comment).
If you do not want the using statement, I guess you can do:
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(File.ReadAllText("//fileLocation", Encoding.GetEncoding("ISO-8859-1")));
Instead of XmlDocument, you can use the XDocument class in the namespace System.Xml.Linq if you refer the assembly System.Xml.Linq.dll (since .NET 3.5). It has static methods like Load(Stream) and Parse(string) which you can use as above.

Accessing the Xml nodes through iteration c#

So I just started using c# about a day ago and haven't had too many issues with it so far but I'm working on an bot for Discord that will pull Pokemon info from an api. I'm currently stuck on traversing through the xml. Here's part of the xml I'm trying to work with:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<stats>
<stat>
<url>https://pokeapi.co/api/v2/stat/6/</url>
<name>speed</name>
</stat>
<effort>0</effort>
<base_stat>100</base_stat>
</stats>
</root>
That's basically an abridged version of my xml doc but there are multiple nodes for "stats". I want to loop the the stats nodes and pull the name of the stat and the value for base stat. Everything I've tried so far throws a null exception error. I having trouble trying to understand how to correctly parse xml so any help would be greatly aprreciated. Also just for extra info I'm working with XmlDocuments. Here's basically what ive tried so far:
XmlDocument pokemon = new XmlDocument();
pokemon.Load("c:\\document.xml");
XmlNodeList xmlNodes = pokemon.SelectNodes("/root/stats");
int count = 0;
foreach (XmlNode xmlNode in xmlNodes)
{
temp.stats[count].val = xmlNode["/stat/name"].InnerText;
temp.stats[count++].num = xmlNode["base_stat"].InnerText;
}
temp is of type poke and stats is just a type I made that has two strings in it, one for the name of the stat and another for the value of the stat. I was able to access other things from the xml document perfectly fine but I'm having trouble pulling from nodes that share the same name.
I believe this will set you on the right path:
XmlNodeList xmlNodes = pokemon.SelectNodes(#"//root/stats");
int count = 0;
foreach (XmlNode xmlNode in xmlNodes)
{
temp.stats[count].val = xmlNode.SelectSingleNode("stat/name").InnerText;
temp.stats[count++].num = xmlNode.SelectSingleNode("base_stat").InnerText;
}
First, to reference the root node with XPath, you need the double forward slashes //. Secondly, you need to use xmlNode.SelectSingleNode(string xPath), and your XPath shouldn't have the leading forward slash.

Can't load files that has xmlns attribute in the first child with XDocument

I am new to XDocument but I have been looking around for a solution to this problem which I couldn't get to fix.
I need to load some kind of XML files (PNML) that comes this way:
<pnml xmlns="http://www.pnml.org/version-2009/grammar/pnml">
<net id="id" type ="http://www.pnml.org/version-2009/grammar/ptnet">
..........</net> </pnml>
And I couldn't get to load these kind of files unless I add "xmlns" as an Attribute to the node net .
Meanwhile, the files I create myself has this xmlns attribute, and I can load them without problems.
While, files that are generated from some other software that I need to be able to use from my software doesn't has this "xmlns" attribute, and if I add it myself to the files generated by this software, I can load those files.
Here's the code I am using to Load :
XDocument doc = XDocument.Load(file);
XNamespace ns = #"http://www.pnml.org/version-2009/grammar/pnml";
foreach (XElement element in doc.Element(ns + "pnml")
.Elements("net").Elements("page").Elements("place"))
{ // Do my loading to "place" nodes for example }
But whenever I try to load a file, it just skips my "foreach" statement, and if I add some line before "foreach" like:
string id= (string) doc.Element(ns + "pnml")
.Element("net").Attribute("id");
it says:
Object reference not set to an instance of an object.
Here's an example of a file generated by my code and also can be read from my code:
<?xml version="1.0" encoding="utf-8"?>
<pnml xmlns="http://www.pnml.org/version-2009/grammar/pnml">
<net id="netid" type="http://www.pnml.org/version-2009/grammar/ptnet" xmlns="">
nodes and information </net> </pnml>
NOTE: I use this code to save my files:
XNamespace ns = #"http://www.pnml.org/version-2009/grammar/pnml";
XDocument doc = new XDocument
(
new XElement(ns+"pnml"
, new XElement("net",new XAttribute("id", net_id), ...));
I found a way to save my files without this "xmlns" attribute, but once I omit it, I can't load it from my code. And the first example I wrote is the standard format and I really need to get ride of the "xmlns" problem.
EDIT: I'm sorry if you got confused, what I want is to be able to load the standard PNML files that doesn't have thise "xmlns" attribute within the "net" node.
What you're missing is that element namespaces are inherited from their parents.
So your XML:
<pnml xmlns="http://www.pnml.org/version-2009/grammar/pnml">
<net id="id" type ="http://www.pnml.org/version-2009/grammar/ptnet">
...
Contains two elements. One is pnml with the namespace http://www.pnml.org/version-2009/grammar/pnml, and the child is net which also has the namespace http://www.pnml.org/version-2009/grammar/pnml.
With this in mind, your query on the existing XML should be:
doc.Element(ns + "pnml").Elements(ns + "net")...
And your code to generate the XML should be:
new XElement(ns + "pnml",
new XElement(ns + "net", new XAttribute("id", net_id), ...));
Try something like this
var result = doc.Element(ns + "pnml").Descendants().Where(x=>x.Name.LocalName=="net")

Issue with loading xml in C# containing google kml

I am trying to access the second element in this xml (google kml type) of file and the issue I am having is I get returned null values for my code unless I remove out the <kml xmlns="http://earth.google.com/kml/2.0"> and the related close from the source file. Here is the code I'm using. (mind you this works if I remove the specified line so what I'm looking for is a clean way to process this file without editing the supplied source file.)
XmlDocument doc = new XmlDocument();
doc.Load("2014_q2.xml");
XmlNodeList xnlNodes = doc.SelectNodes("/kml/Document/Folder");
var Node2Use = xnlNodes.Item(1);
here is the top of the source file:
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.0">
<Document>
<open>1</open>
<Folder>
<name>Pts_2014_q3_point Drawing</name>
<Placemark>
<description>HOLTSVILLE</description>
<name>00501</name>
<Style>
<IconStyle>
<color>ffc0c0c0</color>
I have a break on the var Node2Use = xnlNodes.Item(1); line so I can see the contents and thats where I see that I have a zero value where I should have 2 for Folder (like mentioned I get the 2 when I remove out that kml tagged line.)
You need to include the namespace. Something like this:
XmlDocument doc = new XmlDocument();
doc.Load("2014_q2.xml");
XNamespace ns = "http://earth.google.com/kml/2.0";
XmlNodeList xnlNodes = doc.SelectNodes(ns + "/kml/Document/Folder");

load xml file into memory

I need to load a xml file in memory so I can access it several times from different forms.
The xml is in this format:
<Slides>
<Slide>
<Name>Name 1</Name>
<Value>Value 1</Value>
<Type>Type 1</Type>
</Slide>
<Slide>
<Name>Name 2</Name>
<Value>Value 2</Value>
<Type>Type 2</Type>
</Slide>
</Slides>
I don't want to use a database to store the vars. Is there any other method to store the data in memory?
Right now I'm using a txt file for each slide and streamreader, which I'm sure is not the best option.
EDIT:
I added this code, but will I be able to get the slides every time without reading the xml file again?
var slides = from s in XElement.Load("slides.xml").Elements("Slide")
select s;
foreach (var slide in slides)
{
//code
}
You should use the XDocument Load method: http://msdn.microsoft.com/en-us/library/bb343181.aspx
i think it is better to use XDocument than the XmlDocument... but it depends on your requirements...
The XDocument is more memory optimized than the XmlDocument, and i think they both are easy for use (for getting values from the xml)
See the XmlDocument class. The Load() method does what you want.
First you have to save the xml file in your project file or your hard disk.Then only you can load the xml file in code behind.
You can create xml file dynamically.it will be much better.
using System.Xml;
XmlDocument myxml = new XmlDocument();
myxml.Load("D:/sample.xml");//Load you xml file from you disk what you want to load
string element_1 = myxml.GetElementsByTagName("Name")[0].InnerText;
string element_2 = myxml.GetElementsByTagName("Value")[0].InnerText;
string element_3 = myxml.GetElementsByTagName("Value")[0].InnerText;
string element_4 = myxml.GetElementsByTagName("Name")[1].InnerText;
string element_5 = myxml.GetElementsByTagName("Value")[1].InnerText;
string element_6 = myxml.GetElementsByTagName("Value")[1].InnerText;
Try this program it will help you.

Categories

Resources