getting "null" value for xml - c#

in this xml
<Roots>
<Root Name="cab">element_list</Root>
</Roots>
I want to get the value of attribute Name which is cab and element_list
I have this code
XmlDocument doc = new XmlDocument();
doc.LoadXml("<Root Name=\"cab\">element_list</Root>");
XmlElement root = doc.DocumentElement;
var values = doc.Descendants("Roots").Select(x => new { Name = (string)x.Attribute("Name"), List = (string)x }).ToList();
What I get when I run the debugger is
values> Name = "null", List = "element_list"
I am not understanding why I am getting a null value when I should be getting cab for the attribute Name

XDocument is much easier to work with compared to XmlDocument. Perhaps consider switching to it?
public static void ParseXml()
{
string str = "<Roots><Root Name=\"cab\">element_list</Root></Roots>";
using TextReader textReader = new StringReader(str);
XDocument doc = XDocument.Load(textReader);
var val = doc.Element("Roots").Element("Root").Attribute("Name").Value;
}

Related

How to retrieve attribute from XML file in C#

I'm complete rookie I need to retrieve the value of last id in XML file here is
You can also use XPath within the Xml DOM like this :
string title;
XmlDocument xml = new XmlDocument();
xml.Load("~/purchases.xml");
// Or any other method to load your xml data in the XmlDocument.
// For example if your xml data are in a string, use the LoadXml method.
XmlElement elt = xml.SelectSingleNode("//SubMenu[#id='1']") as XmlElement;
if(elt!=null)
{
name=elt.GetAttribute("title");
}
Reference
As Jon suggested, you can use Linq To XML here.
XElement books = XElement.Load(filePath);
var lastId = books.Descendants("book").Select(x=>Int32.Parse(x.Attribute("ID").Value)).Last();
This will give you the last ID in the current list.You can now create your new Node
books.Add(new XElement("book",new XAttribute("ID",(lastId+1).ToString()),
new XAttribute("title","New Title"),
new XAttribute("price","1234")));
books.Save(filePath);
XmlDocument doc = new XmlDocument();
doc.Load("Yourxmlfilepath.xml");
//Display all the book titles.
XmlNodeList xNodeList = doc.SelectNodes("/bookstore/book");
foreach (XmlNode xNode in xNodeList)
{
var employeeName = xNode.OuterXml;
XmlDocument docnew = new XmlDocument();
docnew.LoadXml(employeeName);
foreach (XmlElement report in docnew.SelectNodes("book"))
{
string ID = report.GetAttribute("ID");
string title = report.GetAttribute("title");
string quantity = report.GetAttribute("quantity");
string price = report.GetAttribute("price");
}
}

Reading specific data from XML file in C#

I want to read specific data from an XML file.
This is what I have come up with so far:
When I run my program without the (if (reader.Name == ControlID)) line reader.Value returns the right value,but when I include the if clause,it returns null
public void GetValue(string ControlID)
{
XmlTextReader reader = new System.Xml.XmlTextReader("D:\\k.xml");
string contents = "";
while (reader.Read())
{
reader.MoveToContent();
if (reader.Name == ControlID)
contents = reader.Value;
}
}
Go through following code:
XmlDocument doc = new XmlDocument();
doc.Load(filename);
string xpath = "/Path/.../config"
foreach (XmlElement elm in doc.SelectNodes(xpath))
{
Console.WriteLine(elm.GetAttribute("id"), elm.GetAttribute("desc"));
}
Using XPathDocument (faster, smaller memory footprint, read-only, weird API):
XPathDocument doc = new XPathDocument(filename);
string xpath = "/PathMasks/Mask[#desc='Mask_X1']/config"
XPathNodeIterator iter = doc.CreateNavigator().Select(xpath);
while (iter.MoveNext())
{
Console.WriteLine(iter.Current.GetAttribute("id"), iter.Current.GetAttribute("desc'));
}
Can also refer this link:
http://support.microsoft.com/kb/307548
This might be helpful to you.
You can try the following code for example xPath query:
XmlDocument doc = new XmlDocument();
doc.Load("k.xml");
XmlNode absoluteNode;
/*
*<?xml version="1.0" encoding="UTF-8"?>
<ParentNode>
<InfoNode>
<ChildNodeProperty>0</ChildNodeProperty>
<ChildNodeProperty>Zero</ChildNodeProperty>
</InfoNode>
<InfoNode>
<ChildNodeProperty>1</ChildNodeProperty>
<ChildNodeProperty>One</ChildNodeProperty>
</InfoNode>
</ParentNode>
*/
int parser = 0
string nodeQuery = "//InfoNode//ChildNodeProperty[text()=" + parser + "]";
absoluteNode = doc.DocumentElement.SelectSingleNode(nodeQuery).ParentNode;
//return value is "Zero" as string
var nodeValue = absoluteNode.ChildNodes[1].InnerText;

Find all the child node of specific value in C#

<main>
<myself>
<pid>1</pid>
<name>abc</name>
</myself>
<myself>
<pid>2</pid>
<name>efg</name>
</myself>
</main>
that is my XML file named simpan. I have two button. next and previous. What i want to do is, all the info will shows off on the TextBox when the user click the button. The searching node will be based on the pid.
Next button will adding 1 value of pid (let's say pid=2) and it will search on the node that have the same value of pid=2. it also will show the name for the pid=2. (showing name=abc)
Same goes to the previous button where it will reduce 1value of pid (pid=1).
Does anybody knows how to do this?
//-------------EDIT------------------
thanks to L.B, im trying to use his code. however i got an error.
is my implementation of code correct?
private void previousList_Click(object sender, EventArgs e)
{
pid = 14;
XDocument xDoc = XDocument.Parse("C:\\Users\\HDAdmin\\Documents\\Fatty\\SliceEngine\\SliceEngine\\bin\\Debug\\simpan.xml");
var name = xDoc.Descendants("myself")
.First(m => (int)m.Element("PatientID") == pid)
.Value;
textETA.Text = name;
////////////////////
}
int pid = 2;
XDocument xDoc = XDocument.Parse(xml); //Load
var name = xDoc.Descendants("myself")
.First(m => (int)m.Element("pid") == pid)
.Element("name")
.Value;
You can use the following XPath to list all Myself tags, then look for what you want using a simple Linq command:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(AppDomain.CurrentDomain.BaseDirectory + "file1.xml");
var resNodes = xmlDoc.SelectNodes("//myself");
XmlNode res = null;
var val = textBox1.Text;
var item = from XmlNode x in resNodes
select x;
foreach (var nodP in item) {
foreach (XmlNode nod in nodP.ChildNodes) {
if (nod.InnerText == val) {
res = nodP;
}
}
}
if (res == null)
// not found!
;
else
// show the result
;
Call me old fashioned but you could use an XPath, for example:
string xml =
#"<main>
<myself>
<pid>1</pid>
<name>abc</name>
</myself>
<myself>
<pid>2</pid>
<name>efg</name>
</myself>
</main>";
using System.Xml;
....
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(xml);
// Replace "2" in the string below with the desired pid
XmlNode xmlNode =
xmlDocument.DocumentElement.SelectSingleNode("myself/name[../pid=2]");
// xmlNode contains the <name>efg</name> XmlElement. For example:
string name = xmlNode.Value;
If it can match multiple nodes, for example there could be multiple <myself> elements with a child element <pid> set to 2, use the following instead:
foreach(XmlNode xmlNode in
xmlDocument.DocumentElement.SelectNodes("myself/name[../pid=2]"))
{
// xmlNode contains the matching <name> element
}
In both cases, the value can be extracted from the XmlNode using the Value property.
public class simpman
{
private static XElement root = XElement.Load("Simpman.xml");
public static string GetItem(int index)
{
XElement item =
(from element in root.Elements("myself")
where (int)element.Element("pid") == index
select element.Element("name")).SingleOrDefault();
return item != null ? item.Value : "Please check the Index";
}
}
Initialize a static itemIndex to 1 and use it further like itemIndex++ (for Next) and itemIndex-- (for Prev).
private void previousList_Click(object sender, EventArgs e)
{
pid = 14;
XDocument xDoc = XDocument.Load(#"C:\Users\HDAdmin\Documents\Fatty\SliceEngine\SliceEngine\bin\Debug\simpan.xml");
var name = xDoc.Root
.Descendants("myself")
.FirstOrDefault(e => e.Element("pid")
.Value
.Equals(pid.ToString(CultureInfo.InvariantCulture)))
.Element("name")
.Value;
textETA.Text = name;
}
XmlDocument doc = new XmlDocument();
FileStream fs = new FileStream(rootXMLPath, FileMode.Open, FileAccess.Read);
doc.Load(fs);
XmlNode node = doc.DocumentElement;
nodeName = "/main/myself";
var child1 = node.SelectSingleNode(nodeName).ChildNodes[0].FirstChild.InnerXml;
var child2 = node.SelectSingleNode(nodeName).ChildNodes[0].LastChild.InnerXml;
var child3 = node.SelectSingleNode(nodeName).ChildNodes[1].FirstChild.InnerXml;
var child4 = node.SelectSingleNode(nodeName).ChildNodes[1].LastChild.InnerXml;

XmlDocument query taking two values

How I can make following query
If I have XmlDocument and it may have following xml
<EquipmentParameterModified dateTime="2011-04-06T12:03:10.00+01:00" parameter="ExtApp">
<Extensions ParameterId="External App Interface" FromParameterValue="" ToParameterValue="DISABLED"/>
</EquipmentParameterModified>
How I can check that I have EquipmentParameterModified and take values of ParameterId and ToParameterValue
Thanks for help.
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load(new StringReader(xmlstr));
XmlNode node = xmldoc.GetElementsByTagName("Extensions").Item(0);
string id = node.Attributes["ParameterId"].Value;
string val = node.Attributes["ToParameterValue"].Value;
Are you trying to find the element given the 2 input search values? What do you want your output to be? If you just want to see that you have a matching element, this code should do the trick:
If yes, try something like this:
public static void Main()
{
var paramId = "External App Interface";
var toParameterValue = "DISABLED";
var xdoc = XDocument.Parse(#"
<EquipmentParameterModified dateTime='2011-04-06T12:03:10.00+01:00' parameter='ExtApp'>
<Extensions ParameterId='External App Interface' FromParameterValue='' ToParameterValue='DISABLED'/>
</EquipmentParameterModified>");
var ret = xdoc.Root
.Elements("Extensions")
.Where(e => e.Attribute("ParameterId").Value == paramId &&
e.Attribute("ToParameterValue").Value == toParameterValue)
.FirstOrDefault();
if (ret != null)
Console.WriteLine(ret.Name);
}
Update for .NET 2.0 & XmlDocument:
public static void Main()
{
var paramId = "External App Interface";
var toParameterValue = "DISABLED";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(#"
<EquipmentParameterModified dateTime='2011-04-06T12:03:10.00+01:00' parameter='ExtApp'>
<Extensions ParameterId='External App Interface' FromParameterValue='' ToParameterValue='DISABLED'/>
</EquipmentParameterModified>");
XmlNode node = xmlDoc.GetElementsByTagName("Extensions")[0];
if (node.Attributes["ParameterId"].Value == paramId &&
node.Attributes["ToParameterValue"].Value == toParameterValue)
{
Console.WriteLine("Found matching node:" + node.Name);
return;
}
}
I recommend using XPath to get the element you're aiming for, do a null check, then get specific attributes of that element, doing a null check on the attribute value before calling the .Value property.

writing to xml attributes

Hey all i have code to write to an xml doc from asp
string filePath = Server.MapPath("../XML/MyXmlDoc.xml");
XmlDocument xmlDoc = new XmlDocument();
try
{
xmlDoc.Load(filePath);
}
catch (System.IO.FileNotFoundException)
{
//if file is not found, create a new xml file
XmlTextWriter xmlWriter = new XmlTextWriter(filePath, System.Text.Encoding.UTF8);
xmlWriter.Formatting = Formatting.Indented;
xmlWriter.WriteProcessingInstruction("xml", "version='1.0' encoding='UTF-8'");
string startElement = "markings";
xmlWriter.WriteStartElement(startElement);
xmlWriter.Close();
xmlDoc.Load(filePath);
}
XmlNode root = xmlDoc.DocumentElement;
XmlElement mainNode = xmlDoc.CreateElement("mark");
XmlElement childNode1 = xmlDoc.CreateElement("studentFirstName");
XmlElement childNode2 = xmlDoc.CreateElement("studentLastName");
XmlElement childNode3 = xmlDoc.CreateElement("className");
XmlElement childNode4 = xmlDoc.CreateElement("marks");
XmlText childTextNode1 = xmlDoc.CreateTextNode("");
XmlText childTextNode2 = xmlDoc.CreateTextNode("");
XmlText childTextNode3 = xmlDoc.CreateTextNode("");
XmlText childTextNode4 = xmlDoc.CreateTextNode("");
root.AppendChild(mainNode);
//this portion can be added to a foreach loop if you need to add multiple records
childTextNode1.Value = "John";
childTextNode2.Value = "Doe";
childTextNode3.Value = "Biology";
childTextNode4.Value = "99%";
mainNode.AppendChild(childNode1);
childNode1.AppendChild(childTextNode1);
mainNode.AppendChild(childNode2);
childNode2.AppendChild(childTextNode2);
mainNode.AppendChild(childNode3);
childNode3.AppendChild(childTextNode3);
mainNode.AppendChild(childNode4);
childNode4.AppendChild(childTextNode4);
//end of loop section
xmlDoc.Save(filePath);
which works fine but i want to store the xml in the following structure
graph
set name="John Doe" value="99";
/graph
instead of
name John Doe /name
value 99 /value
is there a way to store the xml like this? thanks all
You can add an attribute to your XmlElement by using the following syntax (C#) :
XmlAttribute value = xmlDoc.CreateAttribute("value");
childNode1.attributes.appendChild(value);
Hope this helps !
This code will do what you're looking for:
XmlElement graph = xmlDoc.CreateElement("graph");
XmlAttribute name = xmlDoc.CreateAttribute("name");
name.Value = "John Doe";
XmlAttribute value = xmlDoc.CreateAttribute("value");
value.Value = "99";
graph.SetAttributeNode(name);
graph.SetAttributeNode(value);
mainNode.AppendChild(graph);

Categories

Resources