I have this xml file:
<students>
<student>
<name>Mark</name>
<age>20</age>
</student>
<student>
<name>Adam</name>
<age>32</age>
</student>
I want to change the age of Adam, for that I did:
XmlDocument doc = new XmlDocument();
doc.Load("/path/to/sutdents.xml");
XmlNode n = doc.SelectSingleNode("/students/student[name='" + student.name +
"']");
if (n != null)
{
n.SelectNodes("age").Item(0).FirstChild.Value = new_value;
}
but I get "n" as a null value.
I tried another way to do that by searching for the node using foreach and make change, but I get Null Exception:
XmlDocument doc = new XmlDocument();
doc.Load("/path/to/sutdents.xml");
XmlNodeList nodes = doc.SelectNodes("/students/student");
foreach (XmlNode node in nodes)
{
if (node.FirstChild.InnerText == student.name)
{
node.SelectSingleNode("age").InnerText = new_value;
}
}
what I missing here please?
Thanks in advance
I tried to run your code. that is work! check what is the value of student.name.
XML [sutdents.xml]
<?xml version="1.0" standalone="yes"?>
<students>
<student>
<name>Mark</name>
<age>20</age>
</student>
<student>
<name>Adam</name>
<age>32</age>
</student>
</students>
sample code:
XmlDocument doc = new XmlDocument();
doc.Load("sutdents.xml");
XmlNode n = doc.SelectSingleNode("/students/student[name='Adam']");
if (n != null)
{
n.SelectNodes("age").Item(0).FirstChild.Value = "44";
}
doc.Save("sutdents.xml");
i hope this helps;
When Using foreach:
XmlNodeList studentsList = doc.ChildNodes[0].SelectNodes("student");
foreach (XmlNode node in studentsList)
{
if (node.ChildNodes[0].InnerText == student.name) //name
{
node.ChildNodes[1].InnerText = new_value; //age
}
}
Your Code is Correct here is a screen shot of your debugged code with same xml and mentioned code, check you are passing student.name with correct value and case sensitive.
Try this using XDocument:
private static void UpdateXML(string xmlpath, string studentName, int age)
{
var doc = XDocument.Load(xmlpath);
//Get student
var student = doc.Descendants("student").Where(att => att.Element("name") != null && att.Element("name").Value.Equals(studentName)).FirstOrDefault();
if (student != null)
student.Element("age").Value = age.ToString();
doc.Save(xmlpath);
}
Related
I'm trying to read values from following xml (which is previously fetched from FTP):
<?xml version="1.0" encoding="utf-8"?>
<eventdata xmlns="http://www.demoweb.net/xml/eventdata" >
<site>
<sitelink>demotesting</sitelink>
<user>15101991</user>
<measurement>
<nodelink>012019120312064500</nodelink>
<containername>A1</containername>
<time>2020-04-30T11:25:35</time>
<value type="n_v_unitvalue">0.04</value>
<value type="n_v_unitvalue_diff">0.040</value>
</measurement>
<measurement>
<nodelink>012019120312064501</nodelink>
<containername>A2</containername>
<time>2020-04-30T11:25:35</time>
<value type="n_v_unitvalue">0.0</value>
<value type="n_v_unitvalue_diff">-0.001</value>
</measurement>
<measurement>
<nodelink>012019120312064502</nodelink>
<containername>A3</containername>
<time>2020-04-30T11:25:34</time>
<value type="n_v_unitvalue">0.0</value>
<value type="n_v_unitvalue_diff">0.000</value>
</measurement>
</site>
<createdate>2020-04-30T11:25:35</createdate>
</eventdata>
Before I start, file is sucessfully loaded into memory :)
As you can see root node is eventdata, and site is the node where all data is contained.
So basically I need to loop all measurement nodes and get the data.
I also were struggling to get out user node.. here's what I've tried so far:
using (StreamReader xml_reader = new StreamReader(xml_response.GetResponseStream()))
{
string xml = xml_reader.ReadToEnd();
XmlDocument xmldoc = new XmlDocument();
xmldoc.LoadXml(xml);
XmlNodeList mainFileContent = xmldoc.SelectNodes("eventdata");
// XmlNodeList mainFileContent = xmldoc.SelectNodes("eventdata/site");
XmlElement root = xmldoc.DocumentElement;
if (mainFileContent != null)
{
foreach (XmlNode node in mainFileContent)
{
var user = node["user"].InnerText;
}
}
}
What I'm missing?
THANKS GUYS
CHEERS
Your eventdata node has own xmlns declaration, you should properly handle it using XmlNamespaceManager and select the nodes with x:eventdata/x:site XPath expression
var xmldoc = new XmlDocument();
xmldoc.LoadXml(xml);
var nsmgr = new XmlNamespaceManager(xmldoc.NameTable);
nsmgr.AddNamespace("x", xmldoc.DocumentElement.NamespaceURI);
var mainFileContent = xmldoc.SelectNodes("x:eventdata/x:site", nsmgr);
foreach (XmlNode node in mainFileContent)
{
var user = node["user"]?.InnerText;
}
Use below code to read measurement
using (StreamReader xml_reader = new StreamReader(xml_response.GetResponseStream()))
{
string xml = xml_reader.ReadToEnd();
XmlDocument xmldoc = new XmlDocument();
xmldoc.LoadXml(xml);
var nsmgr = new XmlNamespaceManager(xmldoc.NameTable);
nsmgr.AddNamespace("ns", "http://www.demoweb.net/xml/eventdata");
XmlNodeList mainFileContent = xmldoc.SelectNodes("ns:eventdata/ns:site",nsmgr);
XmlElement root = xmldoc.DocumentElement;
if (mainFileContent != null)
{
foreach (XmlNode site in mainFileContent)
{
var user = site["user"].InnerText;
XmlNodeList measurements = site.SelectNodes("ns:measurement", nsmgr);
if (measurements != null)
{
foreach (XmlNode measurement in measurements)
{
var containername = measurement["containername"].InnerText;
var time = measurement["time"].InnerText;
XmlNodeList values = measurement.SelectNodes("ns:value", nsmgr);
if (values != null)
{
foreach (XmlNode value in values)
{
var type = value.Attributes["type"].Value;
var v2 = value.InnerText;
}
}
}
}
}
}
}
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 });
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>
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();
}
My xml will be like below
<Employee>
<Emp>
<Name id="1" link="/office1/manager"></Name>
<Name id="2" link="/office/sweeper"></Name>
<Name id="3" link="/office2/manager"></Name>
</Emp>
</Employee>
I want to get the "id" of the employees who contains string "manager" in "link"
Using linq to xml:
XDocument doc = XDocument.Load("XMLFilePath");
var selectors = from elements in doc.Elements("Employee").Elements("Emp").Elements("Name")
where elements.Attribute("link").Value.Contains("manager")
select elements;
string ids = string.Empty;
foreach (var element in selectors)
{
ids += element.Attribute("id").Value + ",";
}
Also, for loading from string you can use:
XDocument doc = XDocument.Parse(xmlString);
var xDoc = XDocument.Parse(xml); //XDocument.Load(filename)
var ids = xDoc.Descendants("Name")
.Where(n => n.Attribute("link").Value.Contains("/manager"))
.Select(n => n.Attribute("id").Value)
.ToList();
//SELECT THE VALUES FROM XML USING C#
<?xml version="1.0" encoding="iso-8859-1"?>
<CONFIG>
<UsersList>
<SystemName>DOTNET-PC</SystemName>
<UserName>KARTHIKEYAN</UserName>
<ImagePath>C:\Users\DEVELOPER\AppData\Roaming\Office Messenger\assets\insta.jpg</ImagePath>
<PhotoPath>C:\Users\DEVELOPER\AppData\Roaming\Office Messenger\assets\NoPhoto.png</PhotoPath>
<UserStatus>Available</UserStatus>
<CustomStatus>Available</CustomStatus>
<theme>FF8B0000</theme>
</UsersList>
</CONFIG> //XML DOCUMENT
//C#
DataSet ds = new DataSet();
try
{
ds.ReadXml("C:\\config.xml");
}
catch { };
if (ds.Tables.Count > 0)
{
var results = from myRow in ds.Tables[0].AsEnumerable() where myRow.Field<string> ("SystemName") == SystemInformation.ComputerName select myRow;//ds.Tables[0] is <CONFIG> tag //in where SystemName=My system name to select the values from xml
foreach (var cust in results)
{
string _myName = cust["UserName"].ToString();
string _myLogoPath = cust["ImagePath"].ToString();
string _customStatus = cust["CustomStatus"].ToString();
string _myPhotoPath = cust["PhotoPath"].ToString();
}
}
//CREATE XML FROM C#
XDocument xmlDoc = XDocument.Load("C:\\config.xml");
xmlDoc.Root.Add(new XElement("UsersList", new XElement("SystemName", SystemInformation.ComputerName), new XElement("UserName", SystemInformation.ComputerName), new XElement("ImagePath", _filesPath + "\\insta.jpg"), new XElement("PhotoPath", _filesPath + "\\NoPhoto.png"), new XElement("UserStatus", "Available"), new XElement("CustomStatus", "Available"), new XElement("theme", "000000")));
xmlDoc.Save("C:\\config.xml");