Modify existing xml data using xml document in C# - c#

I want to modify XML data given below:
<?xml version="1.0" encoding="utf-8"?>
<allitems>
<item ID="17997" quantity="three">
<available>Y</available>
<last_modified_price>300</last_modified_price>
<edition>2008<edition>
<item>
<item ID="18039" quantity="two">
<available>Y</available>
<last_modified_price>250</last_modified_price>
<edition>2010<edition>
<item>
</allitems>
all elements value should be modified as per set in runtime....
For this I used following code but data is not modified..please help me in getting solution.
XmlDocument modifydoc = new XmlDocument();
modifydoc.Load(#"E:\XMLapp\XMLstorageWEB\patrick\XMLFile1.xml");
var root = modifydoc.GetElementsByTagName("allitems")[0];
var oldelem = root.SelectSingleNode("item[#ID =" + txt_id.Text + "]");
var newelem = modifydoc.CreateElement("item");
root.ReplaceChild(newelem, oldelem);
while (oldelem.ChildNodes.Count != 0)
{
XmlElement available= modifydoc.CreateElement("available");
available.InnerText = ddl_available.SelectedItem.Text;
XmlElement last_modified_price= modifydoc.CreateElement("last_modified_price");
last_modified_price.InnerText = ddl_last_modified_price.SelectedItem.Text;
XmlElement edition= modifydoc.CreateElement("edition");
edition.InnerText = ddl_edition.SelectedItem.Text;
newelem.AppendChild(available);
newelem.AppendChild(last_modified_price);
newelem.AppendChild(edition);
modifydoc.DocumentElement.AppendChild(newelem);
}
while (oldelem.Attributes.Count != 0)
{
newelem.Attributes.Append(oldelem.Attributes[0]);
}
modifydoc.Save(#"E:\XMLapp\XMLstorageWEB\patrick\XMLFile1.xml");
please give me solution..

Not the cleanest way, to add and remove a XmlNode, but just fixing your code I think this is what you want
var txt_id = "17997";
XmlDocument modifydoc = new XmlDocument();
modifydoc.Load(#"c:\temp\so\1.xml");
var root = modifydoc.GetElementsByTagName("allitems")[0];
var oldelem = root.SelectSingleNode("item[#ID =" + txt_id + "]");
var newelem = modifydoc.CreateElement("item");
root.ReplaceChild(newelem, oldelem);
XmlElement available= modifydoc.CreateElement("available");
available.InnerText = "CambiameInnerText";
XmlElement last_modified_price= modifydoc.CreateElement("last_modified_price");
last_modified_price.InnerText = "LastModifed";
XmlElement edition= modifydoc.CreateElement("edition");
edition.InnerText = "SelectedItem";
newelem.AppendChild(available);
newelem.AppendChild(last_modified_price);
newelem.AppendChild(edition);
modifydoc.DocumentElement.AppendChild(newelem);
foreach (XmlAttribute attribute in oldelem.Attributes)
{
newelem.SetAttribute(attribute.Name, attribute.Value);
}
and your xml is not correct, at least the example
<?xml version="1.0" encoding="utf-8"?>
<allitems>
<item ID="17997" quantity="three">
<available>Y</available>
<last_modified_price>300</last_modified_price>
<edition>2008</edition>
</item>
<item ID="18039" quantity="two">
<available>Y</available>
<last_modified_price>250</last_modified_price>
<edition>2010</edition>
</item>
</allitems>

Here is the small and easy example , i use for change the connectionString value in my [web.config]. I hope it's can help you. So easy to adapt for your code ;-)
System.Xml.XmlDocument myXmlDocument = new System.Xml.XmlDocument();
myXmlDocument.Load("myFullPathWebConfig.xml");
foreach (System.Xml.XmlNode node in myXmlDocument["configuration"]["connectionStrings"])
{
if (node.Name == "add")
{
if (node.Attributes.GetNamedItem("name").Value == "SCI2ConnectionString")
{
node.Attributes.GetNamedItem("connectionString").Value = connectionString;
}
}
}

Related

Show xml file info into Listview C#

I'm working on a C# Desktop App and in a module I display the info of a xml file into a listview, I coded my solution with Linq to XML like this
string path = "prueba.xml";
listView1.Items.Clear();
listView1.Columns.Add(path, 400);
XElement doc = XElement.Load(path);
var result = from persona in doc.Elements("persona")
select new{
nombre = Convert.ToString(persona.Element("nombre").Value).Trim(),
ocupacion = Convert.ToString(persona.Element("ocupacion").Value).Trim()
};
foreach (var persona in result)
{
/*ListViewItem item = new ListViewItem(persona.nombre);
item.SubItems.Add(persona.ocupacion);*/
ListViewItem nombre = new ListViewItem("<nombre> " + persona.nombre + " </nombre>");
ListViewItem ocupacion = new ListViewItem("<ocupacion> " + persona.ocupacion + " </ocupacion>");
listView1.Items.Add("<persona>");
listView1.Items.Add(nombre);
listView1.Items.Add(ocupacion);
listView1.Items.Add("</persona>");
listView1.Items.Add("");
}
}
}
and it works very fine, as you can see there are items in the listview that represents the nodes of the xml file, but those items are specific for this xml file
<?xml version="1.0" encoding="utf-8" ?>
<personas>
<persona>
<nombre>Pablo el primero</nombre>
<ocupacion>Programador Cliente-Servidor</ocupacion>
</persona>
<persona>
<nombre>Pablo el segundo</nombre>
<ocupacion>Programador Web</ocupacion>
</persona>
</personas>
as you can see in the C# code, it fits for the xml file above but if I retrieve another xml file with different nodes name like for example
<juego>
<juegos>
<name id="ac"> God of War III </name>
...
</juegos>
</juego>
my code wont show me the nodes <juegos>...</juegos> because it will still display the <person>...</person> nodes because it was created to display only the node <person>...</person> so my question: is there a way to show the information of a xml file into a listview using Linq to XML and at the same time display the info as it is coded in the xml file?
I want to know if I can display this format in teh listview:
<?xml version="1.0" encoding="utf-8" ?>
<personas>
<persona>
<nombre>Pablo el primero</nombre>
<ocupacion>Programador Cliente-Servidor</ocupacion>
</persona>
<persona>
<nombre>Pablo el segundo</nombre>
<ocupacion>Programador Web</ocupacion>
</persona>
</personas>
You don't have to use linq to do it, you can simply query the elements of your document.
listView1.View = System.Windows.Forms.View.Details;
listView1.AutoArrange = false;
listView1.Alignment = ListViewAlignment.Left;
listView1.Items.Clear();
listView1.Columns.Add("XML",400);
string xml =
#"<?xml version=""1.0"" encoding=""utf-8"" ?>
<personas>
<persona>
<nombre>Pablo el primero</nombre>
<ocupacion>Programador Cliente-Servidor</ocupacion>
</persona>
<persona>
<nombre>Pablo el segundo</nombre>
<ocupacion>Programador Web</ocupacion>
</persona>
</personas>";
XDocument doc = XDocument.Parse(xml);
List<ListViewItem> ItemList = new List<ListViewItem>();
foreach (XElement elem in doc.Elements())
{
AddNewItemToList(ItemList, elem);
}
listView1.Items.AddRange(ItemList.ToArray());
...
private void AddNewItemToList(List<ListViewItem> ItemList, XElement elem)
{
string attributes = "";
if (elem.HasAttributes)
{
foreach (XAttribute attr in elem.Attributes())
{
attributes += " " + attr.Name + "=\"" + attr.Value + "\"";
}
}
if (elem.HasElements)
{
ItemList.Add(new ListViewItem("<" + elem.Name + attributes + ">"));
foreach (XElement childElem in elem.Elements())
{
AddNewItemToList(ItemList, childElem);
}
ItemList.Add(new ListViewItem("</" + elem.Name + ">"));
}
else
{
ItemList.Add(new ListViewItem("<" + elem.Name + attributes + ">" + elem.Value + "</" + elem.Name + ">"));
}
}

How to get attribute xml without loop c#

i have xml file like this
> <?xml version='1.0' ?>
<config>
<app>
<app version="1.1.0" />
> </app>
</config>
and i want to read attribute version from node app
without any loop like this
while(reader.read()) or foreach etc.
Thanks
XmlDocument document = new XmlDocument();
document.Load("D:/source.xml");
XmlNode appVersion1 = document.SelectSingleNode("//app[#version]/#version");
XmlNode appVersion2 = document["config"]["app"]["app"].Attributes["version"];
Console.WriteLine("{0}, {1}",
appVersion1.Value,
appVersion2.Value);
You can do it this way.
XmlDocument doc = new XmlDocument();
string str = "<config><app><app version=" + "\"1.1.0\"" + "/></app></config>";
doc.LoadXml(str);
var nodes = doc.GetElementsByTagName("app");
foreach (XmlNode node in nodes)
{
if (node.Attributes["version"] != null)
{
string version = node.Attributes["version"].Value;
}
}
And you need to this for loop cause you got two nodes with same name App.
If you have a single node with name App,
XmlDocument doc = new XmlDocument();
string str = "<config><app version=" + "\"1.1.0\"" + "/></config>";
doc.LoadXml(str);
var node = doc.SelectSingleNode("//app");
if (node.Attributes["version"] != null)
{
string version = node.Attributes["version"].Value;
Console.WriteLine(version);
}
You can use linq to do
string stringXml= "yourXml Here";
XElement xdoc = XElement.Parse(stringXml);
var result= xdoc.Descendants("app").FirstOrDefault(x=> x.Attribute("version") != null).attribute("version").Value;
or:
var result = xdoc.Descendants("app").Where(x => x.Attribute("version") != null)
.Select(x => new { Version = x.Value });

Update xml file with xmltextReader in c#

I have xml file like this test.xml:
<?xml version="1.0" encoding="utf-8" ?>
<Message>
<Item Name ="msg1" Status ="false"/>
<Item Name="msg2" Status="false"/>
</Message>
System.Xml.XmlTextReader textReader = new System.Xml.XmlTextReader(test.xml);
System.Xml.XmlDocument xdoc = new System.Xml.XmlDocument();
xdoc.Load(test.xml);
var testreader = xdoc.DocumentElement.ChildNodes;
string name = string.Empty;
string value = string.Empty;
if (message.MsgType == 10005)
{
value = "true";
}
else if (message.MsgType == 10002)
{
value = "false";
}
foreach (var mychild in testreader)
{
var childatt = ((System.Xml.XmlElement)mychild);
name = childatt.Attributes["Name"].Value;
value = childatt.Attributes["Status"].Value;
}
What I have to do to following thing:
I have to save updated value in xml file with xmltestReader and xmldocument
I'm getting request from third client about messageID so I have to check it's exist in xml file or not (e.g get request for msg1 so I have to match it xml file it's there or not).
hope I'm clear with my question.
//Get Message
//txtsearch text u have to pass message Id
var xmlFilePath = Server.MapPath("Test.xml");
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(xmlFilePath);
XmlNodeList nodeList = xmlDoc.DocumentElement.SelectNodes("/TableMessage/Message");
string msgID = "",msgname="";
foreach (XmlNode node in nodeList)
{
if (node.SelectSingleNode("Message_Details").InnerText == "True" && node.SelectSingleNode("Message_id").InnerText==txtsearchtext.Text)
{
msgID = node.SelectSingleNode("Message_id").InnerText;
msgname = node.SelectSingleNode("Message_name").InnerText;
}
}
//store Updated Xml in ur project xml
//get the information from end user and pass the value to correspoding fields
XmlDocument xmlEmloyeeDoc = new XmlDocument();
xmlEmloyeeDoc.Load(Server.MapPath("~/Test.xml"));
XmlElement ParentElement = xmlEmloyeeDoc.CreateElement("Message");
XmlElement ID = xmlEmloyeeDoc.CreateElement("Message_id");
ID.InnerText = "6";
XmlElement message = xmlEmloyeeDoc.CreateElement("Message_name");
message.InnerText = "Message6";
XmlElement Details = xmlEmloyeeDoc.CreateElement("Message_Details");
Details.InnerText = "True";
ParentElement.AppendChild(ID);
ParentElement.AppendChild(message);
ParentElement.AppendChild(Details);
xmlEmloyeeDoc.DocumentElement.AppendChild(ParentElement);
xmlEmloyeeDoc.Save(Server.MapPath("~/Test.xml"));
I hope that code will help u
you will customize ur xml file like this
<?xml version="1.0" encoding="utf-8"?>
<TableMessage>
<Message>
<Message_id>Message1</Message_id>
<Message_name>Message1</Message_name>
<Message_Details>True</Message_Details>
</Message>
<Message>
<Message_id>Message2</Message_id>
<Message_name>Message2</Message_name>
<Message_Details>True</Message_Details>
</Message>
<Message>
<Message_id>Message3</Message_id>
<Message_name>Message3</Message_name>
<Message_Details>False</Message_Details>
</Message>
</TableMessage>

Saving to xml file

I have a question about updating data in current xml file.
For example I want to change Radius to "50"
XML file:
<?xml version="1.0" encoding="utf-8"?>
<Settings>
<Radius>25</Radius>
<Length>40</Length>
<Height>15</Height>
<Name>Oks</Name>
</Settings>
I can read these settings with this code:
public void GetSettings()
{
XmlDocument xml = new XmlDocument();
xml.Load(location);
XmlNodeList xnList = xml.SelectNodes("/Settings");
foreach (XmlNode xn in xnList)
{
tb_height.Text = xn["Height"].InnerText;
tb_lenght.Text = xn["Length"].InnerText;
tb_radius.Text = xn["Radius"].InnerText;
tb_name.Text = xn["Name"].InnerText;
}
}
Not really sure what you are trying to do.
but to save your file, you can simply:
xml.Save(PathToSaveTo);
Got it working with
public void SaveSettings()
{
XmlDocument xml = new XmlDocument();
xml.Load(location);
XmlNodeList xnList = xml.SelectNodes("/Settings");
XmlNode xn = xml.SelectNodes("/Settings").Item(0);
xn["Height"].InnerText = tb_height.Text;
xn["Length"].InnerText = tb_lenght.Text;
xn["Radius"].InnerText = tb_radius.Text;
xn["Name"].InnerText = tb_name.Text;
xml.Save(location);
}

Querying XML document

I am trying to query an xml document, but this code doesn't read xml parts with closed tag notation but reads fine xelement. Can anyone spot what I'm doing wrong?
I have program generated XML document which gives closed tagged file hence its an issue now..
<?xml version="1.0" encoding="utf-8" ?>
<Student>
<Person name="John" city="Auckland" country="NZ" />
<Person>
<Course>GDICT-CN</Course>
<Level>7</Level>
<Credit>120</Credit>
<Date>129971035565221298</Date>
</Person>
<Person>
<Course>GDICT-CN</Course>
<Level>7</Level>
<Credit>120</Credit>
<Date>129971036040828501</Date>
</Person>
</Student>
class Program
{
static void Main(string[] args)
{
XDocument xDoc = XDocument.Load(AppDomain.CurrentDomain.BaseDirectory + "Customers.xml");
IEnumerable<XElement> rows = from row in xDoc.Descendants("Person") select row;
foreach(XElement xEle in rows)
{
IEnumerable<XAttribute>attlist = from att in xEle.DescendantsAndSelf().Attributes() select att;
foreach(XAttribute xatt in attlist)
{
Console.WriteLine(xatt);
}
Console.WriteLine("-------------------------------------------");
}
Console.ReadLine();
}
}
Since you have added Course and other attributes as XElement, so you need to loop on XElements instead of attributes -
foreach (XElement xEle in rows)
{
IEnumerable<XAttribute> attlist = from att in xEle.DescendantsAndSelf()
.Attributes() select att;
foreach (XAttribute xatt in attlist)
{
Console.WriteLine(xatt);
}
foreach (XElement elemnt in xEle.Descendants())
{
Console.WriteLine(elemnt.Value);
}
Console.WriteLine("-------------------------------------------");
}
First you must navigate to Person level and iterate through Persons, then for each Person you can iterate through its attributes.
private static void Main(string[] args)
{
//string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
//XDocument xDoc = XDocument.Load(path + "\\Student Data\\data.xml");
XDocument xDoc = XDocument.Load(AppDomain.CurrentDomain.BaseDirectory + "Customers.xml");
IEnumerable<XElement> xElements = xDoc.Descendants("Person");
foreach (XElement element in xElements)
{
foreach (XAttribute attribute in element.Attributes())
{
Console.WriteLine(attribute);
}
Console.WriteLine("-------------------------------------------");
}
Console.ReadLine();
}

Categories