This is what my xml looks like:
<Runners>
<Runner>
<RunnersBadge>
123
</RunnersBadge>
<Times>
</Times>
</Runner>
<Runner>
<RunnersBadge>
456
</RunnersBadge>
<Times>
</Times>
</Runner>
I can find the specific runner, for example 123 with this code:
//loadxml
string findrunner = "123";
XmlNodelist nodelist = "xmldocument".SelectNodes("Runners\Runner")
foreach(XmlNode node in nodelist)
{
if ( node["RunnersBadge"].InnerText.Equals(findrunner)
{
//This is how far I get, I can find the runner because if I put a value inside times
//and output it in a message box, it is showing the proper one for runner 123.
}
How would I go about adding a node inside called so the xml looks like this:
<Runners>
<Runner>
<RunnersBadge>
123
</RunnersBadge>
<Times>
<LapTime>
</LapTime>
<LapTime>
</LapTime>
</Times>
</Runner>
<Runner>
<RunnersBadge>
456
</RunnersBadge>
<Times>
</Times>
</Runner>
I can add inside using CreateElement("LapTime") then ApphendChild and then saving it. That just creates the new node/element inside , how would I go about going one more level so I can add the new node/element inside ?
The following code should add the new node up to two levels as required...
string message = "<Insert XML Here>";
string findrunner = "123";
XmlDocument document = new XmlDocument();
document.LoadXml(message);
XmlNodeList nodelist = document.SelectNodes("//Runner");
foreach (XmlNode node in nodelist)
{
foreach (XmlNode child in node.ChildNodes)
{
if (child.Name == "RunnersBadge" && child.InnerText.Equals(findrunner))
{
XmlNode Times = null;
XmlNode LapTime = null;
if ((Times = node.SelectSingleNode("//Times")) == null)
{
Times = document.CreateNode(XmlNodeType.Element, "Times", "");
node.AppendChild(Times);
}
LapTime = document.CreateNode(XmlNodeType.Element, "LapTime", "");
LapTime.InnerText = ""; // Set Value Here
Times.AppendChild(LapTime);
break;
}
}
}
Related
static void Main(string[] args)
{
WebClient _httpReq = new WebClient(); // to talk to the web only for get method
string response = _httpReq.DownloadString("https://open-ic.epic.com/FHIR/api/FHIR/DSTU2/Patient?family=Argonaut&given=Jason");
Console.WriteLine(response);\\prints the xml string fetched from FHIR provider EPIC
XmlDocument xml = new XmlDocument();
xml.LoadXml(response); // suppose that myXmlString contains "<Names>...</Names>"
XmlNodeList xnList = xml.SelectNodes("/entry/resource/patient/name");
// here code is trying to extract the name attribute
foreach (XmlNode xn in xnList)
{
string firstName = xn["family value"].InnerText;
string lastName = xn["given value"].InnerText;
Console.WriteLine("Name: {0} {1}", firstName, lastName);
//print the first name and last name of the patient
}
Console.ReadLine();
}
i do it like this:
XmlDocument MyDocument = new XmlDocument();
MyDocument.Load("...");
XmlNode MyNode = MyDocument.SelectSingleNode("/Node_Name");
foreach (XmlAttribute MyAttribute in MyNode.Attributes)
{
if (MyAttribute.Name == "Attribute_Name")
{
object Value = MyAttribute.Value;
break;
}
}
Review XPath. Once you start understanding it, you will find it efficient and easier to code than iterating through lists. It also lets you directly get the nodes/attributes you want.
Then the code would be something similar to
string attrVal = doc.SelectSingleNode("/entry/resource/patient/#name").Value;
Or you can Load XML in XMlDocument and You can fetch element and out of that element you can read specific atairbute,
XmlDocument doc = new XmlDocument();
doc.LoadXml("<reply success=\"true\">More nodes go here</reply>");
XmlElement root = doc.DocumentElement;
string s = root.Attributes["success"].Value;
I am using an xml file to import into the database using the below code
CS:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(pathPMO + "Data.xml");
XmlNodeList nodeList = xmlDoc.DocumentElement.SelectNodes("/DocumentElement/Profile");
bool insertProfile = false;
foreach (XmlNode node in nodeList)
{
strYear = node.SelectSingleNode("Profile_x0020_Year").InnerText;
strID = node.SelectSingleNode("Profile_x0020_ID").InnerText;
strLead = node.SelectSingleNode("Profile_x0020_Leader").InnerText;
insertProfile = ImportProfile(strYear, strID, strLead);
}
For instance the profile leader values are empty for certain rows and when I try to insert them I get an error object not set to an instance of an object because of that particular element missing in few rows.
Can anyone suggest how to solve this?
You should ensure that each XmlNode object is not null. You can use a simple method like that:
private string GetXmlNodeString(string nodeName, XmlNode node)
{
if(String.IsNullOrWhiteSpace(nodeName))
return String.Empty;
var singleNode = node.SelectSingleNode(nodeName);
if(singleNode ==null)
return String.Empty;
return singleNode.InnerText;
}
then change your code like that:
foreach (XmlNode node in nodeList)
{
strYear = GetXmlNodeString("Profile_x0020_Year",node);
strID = GetXmlNodeString("Profile_x0020_ID",node);
strLead = GetXmlNodeString("Profile_x0020_Leader",node);
insertProfile = ImportProfile(strYear, strID, strLead);
}
I am trying to populate an array with the inner text or value of a XML tag. I can loop though the nodes of the tag i am just having an issue pulling out the stored value.
I am looping though the child nodes of the Properties Tag, XML at bottom of Question.
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("C://Users//Shaun//Documents//Visual Studio 2010//Projects//LightStoneTestService//LightStoneTestService//FileTest//Testdo.xml");
//XmlNodeList dataNodes = xmlDoc.SelectNodes("//Properties");
XmlNodeList oXMlNodeList = xmlDoc.GetElementsByTagName("Properties");
for (int Count = 0; Count < 27; Count++)
{
foreach (XmlNode node in oXMlNodeList)
{
int Max = node.ChildNodes.Count;
foreach (XmlNode childNode in node.ChildNodes) //For each child node in FieldData
{
if (ArrayProperties[Count].LightStoneTag == childNode.Name)
{
ArrayProperties[Count].Value = node.SelectSingleNode(ArrayProperties[Count].LightStoneTag).InnerText;
}
}
}
}
***** My Xml file looks as follows:
<NewDataSet>
<RequestData xmlns="RequestData">
<Req_ID>3204eba5-07f4-4e83-8b46-d89fa1d70bf6</Req_ID>
</RequestData>
<Properties xmlns="Properties">
<sr_id>19374324</sr_id>
<prop_id>9841107</prop_id>
<DEED_ID>21</DEED_ID>
<PROPTYPE_ID>2</PROPTYPE_ID>
<SS_ID>2315</SS_ID>
<NAD_ID>3048001</NAD_ID>
<property_type>SS</property_type>
<PROVINCE>GA</PROVINCE>
<MUNICNAME>CITY OF JOHANNESBURG</MUNICNAME>
<DEEDTOWN>ALLENS NEK</DEEDTOWN>
<SECTIONAL_TITLE>SS GREENHILLS</SECTIONAL_TITLE>
<UNIT>15</UNIT>
<TownShip>ALLENS NEK</TownShip>
<Purchase_Price>236500</Purchase_Price>
<Purchase_Date>20031020</Purchase_Date>
<Bond_Number>SB37369/2006</Bond_Number>
<Township_alt>ALLEN'S NEK EXT 32</Township_alt>
<RE>false</RE>
</Properties>
</NewDataSet>
It's the namespace issue. Add this portion of code before the for loop:
NameTable nt = new NameTable();
nt.Add("Properties");
XmlNamespaceManager nsmgr = new XmlNamespaceManager(nt);
nsmgr.AddNamespace("ns1", "Properties");
Change the line where you retrieve InnerText to:
ArrayProperties[Count].Value = node
.SelectSingleNode(
String.Concat("//ns1:", ArrayProperties[Count].LightStoneTag),
nsmgr)
.InnerText;
i have that xml file :
<?xml version="1.0" encoding="utf-8"?>
<reminders>
<reminder>
<Title>Alarm1</Title>
<Description>Desc1</Description>
<Time>03/07/2012 10:11AM</Time>
<snooze>1</snooze>
<repeat>None</repeat>
</reminder>
</reminders>
And i want to modify the innertext from Alarm1 to another value so i wrote that code which actually duplicate the entire node .
XmlDocument xml = new XmlDocument();
xml.Load("0.xml");
XmlNodeList elements = xml.SelectNodes("//reminders");
foreach (XmlNode element in elements)
{
if (element.InnerText == "Alarm1")
{
XmlNode newvalue = xml.CreateElement("MODIFIED");
element.ReplaceChild(newvalue, element);
xml.Save("0.xml");
}
}
And then tried another code :
foreach (XmlElement element in xml.SelectNodes("//reminder"))
{
if (element.InnerText == "Alarm1")
{
XmlNode newvalue = xml.CreateElement("MODIFIED");
element.ReplaceChild(newvalue, element);
xml.Save("0.xml");
}
}
But also doesn`t work....
EDIT 1 : [Figured out a new code]
XmlDocument xml = new XmlDocument();
xml.Load("0.xml");
foreach (XmlElement element in xml.SelectNodes("//reminder"))
{
foreach (XmlElement element1 in element)
{
if (element.SelectSingleNode("//Title").InnerText == "Alarm1")
{
XmlNode newvalue = xml.CreateElement("MODIFIED");
element.ReplaceChild(newvalue, element1);
xml.Save("0.xml");
}
}
}
But it made the Alarm1 becomes
<MODIFIED />
EDIT 2 : [I SOLVED IT :D]
Okay here is the code i could figure out :
XmlDocument xml = new XmlDocument();
xml.Load("0.xml");
foreach (XmlElement element in xml.SelectNodes("//reminder"))
{
foreach (XmlElement element1 in element)
{
if (element.SelectSingleNode("//Title").InnerText == "Alarm1")
{
MessageBox.Show(element1.InnerText);
XmlNode newvalue = xml.CreateElement("Title");
newvalue.InnerText = "MODIFIED";
element.ReplaceChild(newvalue, element1);
xml.Save("0.xml");
}
}
}
I`ll really appreciate your helps and thanks.
Try this:
xml.SelectSingleNode("//reminder/Title").InnerText = "NewValue";
Your foreach line is simply looping through a list of elements called "reminders", not it's child nodes.
Take a look at this xpath tutorial for more information:
http://www.w3schools.com/xpath/xpath_intro.asp
If you want to use linq with xml (I find it the best way) then you will want to use the System.Xml.Linq namespace. The classes in that namespace are all prefixed with just X not Xml. The functionality in this namespace is newer, better and much easier to manipulate with Linq.
var xml = XDocument.Load("0.xml");
var alarm1 = xml.Descendants("reminder")
.Single(r => r.Element("Title") == "Alarm1");
This code will give you a variable, alarm1 that is the reminder that has a title node of "Alarm1."
From that point its not clear to me exactly what you want to modify. If you just want to change the title then ...
alarm1.Element("Title").Value = "MODIFIED";
xml.Save("0.xml");
XDocument doc = XDocument.Load("0.xml");
IEnumerable<XElement> rech =
from el in doc.Root.Elements("reminder")
where (string)el.Element("Title") == "Alarm1"
select el;
if (rech.Count() != 0)
{
foreach (XElement el in rech)
{
el.Element("Title").SetValue("NEW TITLE");
}
}
doc.Save("0.xml");
XDocument xDoc = XDocument.Load(.....);
xDoc.Descendants("Title").First().Value = "New Value";
xDoc.Save(...)
XmlDocument xml = new XmlDocument();
xml.Load(...);
var newTitle = "MODIFIED";
var title_node = xml.GetElementsByTagName("Title");
if(!string.IsNullOrEmpty(newTitle) && title_node.Count > 0)
{
title_node[0].InnerText = newTitle;
}
I've been using this code to try and get data from the google weather API, but I never get even close to pulling out what i want.
My goal is to look at:
<forecast_information>
**<city data="london uk"/>**
<postal_code data="london uk"/>
<latitude_e6 data=""/>
<longitude_e6 data=""/>
<forecast_date data="2011-10-09"/>
<current_date_time data="2011-10-09 12:50:00 +0000"/>
<unit_system data="US"/>
</forecast_information>
<current_conditions>
<condition data="Partly Cloudy"/>
<temp_f data="68"/>
**<temp_c data="20"/>**
**<humidity data="Humidity: 68%"/>**
<icon data="/ig/images/weather/partly_cloudy.gif"/>
**<wind_condition data="Wind: W at 22 mph"/>**
</current_conditions>
And only return the text of the child nodes.
So the result would be:
City: London UK
Temp: 20c
Humidity: 68%
Wind: 22mph
Currently I am trying to use this, but got nowhere...
XmlDocument doc = new XmlDocument();
XmlNodeList _list = null;
doc.Load("http://www.google.com/ig/api?weather=london+uk");
_list = doc.GetElementsByTagName("forecast_information/");
foreach (XmlNode node in _list)
{
history.AppendText(Environment.NewLine + "City : " + node.InnerText);
}
//NOTE, currently code is set to display ALL child nodes
Perhaps someone can shed some light on the matter?
Maybe you should use node.SelectSingleNode("city").Attributes["data"].Value instead of node.InnerText
--EDIT--
This works for me
XmlDocument doc = new XmlDocument();
doc.Load("http://www.google.com/ig/api?weather=london+uk");
var list = doc.GetElementsByTagName("forecast_information");
foreach (XmlNode node in list)
{
Console.WriteLine("City : " + node.SelectSingleNode("city").Attributes["data"].Value);
}
list = doc.GetElementsByTagName("current_conditions");
foreach (XmlNode node in list)
{
foreach (XmlNode childnode in node.ChildNodes)
{
Console.Write(childnode.Attributes["data"].Value + " ");
}
}
Change that to
history.AppendText(Environment.NewLine + "City : " + node.GetAttribute("data"));
using System.Xml.Linq;
using System.Xml.XPath;
XElement doc = XElement.Load("http://www.google.com/ig/api?weather=london+uk");
string theCity = doc.XPathSelectElement(#"weather/forecast_information/city").Attribute("data").Value;
string theTemp = doc.XPathSelectElement(#"weather/current_conditions/temp_c").Attribute("data").Value;
string theHumid = doc.XPathSelectElement(#"weather/current_conditions/humidity").Attribute("data").Value;
string theWind = doc.XPathSelectElement(#"weather/current_conditions/wind_condition").Attribute("data").Value;
string resultString = String.Format("City : {0} Temp : {1}c {2} {3}", theCity, theTemp, theHumid, theWind);