C# XmlDocument.Item property doesn't actually exist? - c#

According to MSDN there's an "Item" property associated with the XmlDocument class:
http://msdn.microsoft.com/en-us/library/system.xml.xmldocument.aspx
I can't seem to get it to work though.
XmlDocument doc = new XmlDocument();
doc.LoadXml("<item><name>wrench</name></item>");
string myItem = doc.Item["item/name"].InnerText;
...fails to compile for example. What's the correct way to use this property if it does exist?

An indexer in C# is exposed as a parametrized property called Item to other languages.
In C#, just use indexer syntax:
var result = someObject["something"];

An alternate approach, using LINQtoXML
Assuming your XML is going to be always in that structure.
string thatXml="<item><name>wrench</name></item>";
XElement elm =XElement.Parse(thatXml);
string thatValue = elm.Element("name").Value;

Related

Reading values from within an XNode

I have some code that is returning a XNode to me which looks like this:
<File>
<Component>Main</Component>
<Path>C:\Main\</Path>
<FileName>main.txt</FileName>
</File>
I need to have some C# code that will be able to pull out the value of Path for example (C:\Main). I know that if I was using an XML node I could do it like this:
String filePath = xmlNode["Path"].InnerText;
Does anybody know what the equivalent would be for an XNode? Any help is much appreciated!
Do you have to have it returning an XNode rather than an XElement? With an XElement it's simpler than with an XNode:
string filePath = fileElement.Element("Path").Value;
That will find the first Path element, and will throw a NullReferenceException if there aren't any. An alternative if you're happy to get null if there aren't any would be:
string filePath = (string) fileElement.Element("Path");
If you're really stuck with XNode, you'll either have to cast to XElement or possibly XContainer.
You can convert your XNode into XElement to access to its properties, my example:
XNode lastNode = myXElement.LastNode;
//if I want to get the 'ID' attribute
string id = (lastNode as XElement).Attribute("ID").Value;
Casting XNode to XElement works for the individual element to retrieve its value or attributes. But you won't be able to use myXelement.Elements("XXX") to get nested elements. For that you can use xmlNode.Nodes().
This should work:
var nodes = xmlNode.Nodes();//Get all nodes under 'File'
var fileNameNode = nodes.Where(el => ((XElement)el).Name.LocalName == "FileName")
.FirstOrDefault();
string filePath = ((XElement)fileNameNode).Value;
You may use this:
XElement xtr = XElement.Load("path/to/your/xml/file");
String filePath = xtr.Descendants("Path").Single().Value;
If you import System.Xml.XPath you can use XPathSelectElement like this on the XNode object:
String component = xmlNode.XPathSelectElement("Component");
String path = xmlNode.XPathSelectElement("Path");
String fileName = xmlNode.XPathSelectElement("FileName");
It depends on what convcrete objets is the abstract XNode. From XNode Class:
XNode is an abstract common base class for the following types:
XComment
XContainer: can be XDocument or XElement
XDocumentType
XProcessingInstruction
XText
So you need to check if you can cast it to an XDocument or an XElement, and use their methods, or use LINQ to XML:
For example:
Best way to query XDocument with LINQ?
Querying an XDocument vs. Querying an XElement (C#)
XNode xnode
string value = (xnode as XElement).Value;
we can get the value form XElement object so we need to cast XNode to XElement first
should work

Get xml node value as string C#

I've been trying to pull the value of the XML node into a string. Here is what the XML looks like:
<currentvin value="1FTWW31R08EB18119" />
I can't seem to figure out how to grab that value. I didn't write this XML, by the way. So far I have tried several approaches, including the following:
public void xmlParse(string filePath)
{
XmlDocument xml = new XmlDocument();
xml.Load(filePath);
XmlNode currentVin = xml.SelectSingleNode("/currentvin");
string xmlVin = currentVin.Value;
Console.WriteLine(xmlVin);
}
Which doesn't work. I then tried:
public void xmlParse(string filePath)
{
XmlDocument xml = new XmlDocument();
xml.Load(filePath);
string xmlVin = xml.SelectSingleNode("/currentvin").Value;
Console.WriteLine(xmlVin);
}
But that doesn't work either. I am getting a null reference exception stating that Object reference not set to an instance of an object. Any ideas?
I think you're confusing the Value property of the XmlNode class, with an XML attribute named "value".
value is an attribute in your xml so either modify your xpath query to be
xml.SelectSingleNode("/currentvin/#value").Value
Or user the Attributes collection of the selected XmlNode.
You are looking for the value of the attribute "value" (that's a handful) not the value of the node itself - so you have to use the Attribute property:
string xmlVin = xml.SelectSingleNode("/currentvin").Attributes["value"].Value;
Or in the first version:
XmlNode currentVin = xml.SelectSingleNode("/currentvin");
string xmlVin = currentVin.Attributes["value"].Value;
If your entire XML contains only this node then it could be xml.DocumentElement.Attributes["value"].Value;

Get content of XML node using c#

simple question but I've been dinking around with it for an hour and it's really starting to frustrate me. I have XML that looks like this:
<TimelineInfo>
<PreTrialEd>Not Started</PreTrialEd>
<Ambassador>Problem</Ambassador>
<PsychEval>Completed</PsychEval>
</TimelineInfo>
And all I want to do is use C# to get the string stored between <Ambassador> and </Ambassador>.
So far I have:
XmlDocument doc = new XmlDocument();
doc.Load("C:\\test.xml");
XmlNode x = doc.SelectSingleNode("/TimelineInfo/Ambassador");
which selects the note just fine, now how in the world do I get the content in there?
May I suggest having a look at LINQ-to-XML (System.Xml.Linq)?
var doc = XDocument.Load("C:\\test.xml");
string result = (string)doc.Root.Element("Ambassador");
LINQ-to-XML is much more friendly than the Xml* classes (System.Xml).
Otherwise you should be able to get the value of the element by retrieving the InnerText property.
string result = x.InnerText;
The InnerText property should work fine for you.
http://msdn.microsoft.com/en-us/library/system.xml.xmlnode.innertext.aspx
FWIW, you might consider switching API to linq-to-xml (XElement and friends) as IMHO it's a friendly, easier API to interact with.
System.Xml version (NOTE: no casting to XmlElement needed)
var xml = #"<TimelineInfo>
<PreTrialEd>Not Started</PreTrialEd>
<Ambassador>Problem</Ambassador>
<PsychEval>Completed</PsychEval>
</TimelineInfo>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
var node = doc.SelectSingleNode("/TimelineInfo/Ambassador");
Console.WriteLine(node.InnerText);
linq-to-xml version:
var xml = #"<TimelineInfo>
<PreTrialEd>Not Started</PreTrialEd>
<Ambassador>Problem</Ambassador>
<PsychEval>Completed</PsychEval>
</TimelineInfo>";
var root = XElement.Parse(xml);
string ambassador = (string)root.Element("Ambassador");
Console.WriteLine(ambassador);
XmlDocument doc = new XmlDocument();
doc.Load("C:\\test.xml");
XmlNode x = doc.SelectSingleNode("/TimelineInfo/Ambassador");
x.InnerText will return the contents
Try using Linq to XML - it provides a very easy way to query xml datasources - http://msdn.microsoft.com/en-us/library/bb387098%28v=VS.100%29.aspx

How to get parameter values from an XmlNode in C#

How do I get the values for parameters in a XmlNode tag. For example:
<weather time-layout="k-p24h-n7-1">
<name>Weather Type, Coverage, and Intensity</name>
<weather-conditions weather-summary="Mostly Sunny"/>
</weather>
I want to get the value for the parameter 'weather-summary' in the node 'weather-conditions'.
var node = xmldoc.SelectSingleNode("weather/weather-conditions");
var attr = node.Attributes["weather-summary"];
In the interest of completeness, the .Net 3.5 way should be given as well:
Assuming
XDocument doc = XDocument.Parse(#"<weather time-layout='k-p24h-n7-1'>
<name>Weather Type, Coverage, and Intensity</name>
<weather-conditions weather-summary='Mostly Sunny'/></weather>");
Then either
return doc.Element("weather").Element("weather-conditions").Attribute("weather-summary").Value;
Or
return doc.Descendants("weather-conditions").First().Attribute("weather-summary").Value;
Will give you the same answer.

XML and the & character

I need to pass the & character inside an XML element, but its not liking it, here is a code sample:
XmlDocument doc = new XmlDocument();
XmlElement batch = doc.CreateElement("Batch");
string item = "<field>http://mylink.com/page.aspx?id=1&disp=2</field>"
batch.InnerXml = item;
Its absolutely crucial I put this link inside, so does anyone know how to get around this?
Thank you
You need to escape it as &.
As people are saying, escaping the element will work. However, I find this a little cleaner:
XmlDocument doc = new XmlDocument();
XmlElement batch = doc.CreateElement("Batch");
XmlElement field = doc.CreateElement("field");
string link = "http://mylink.com/page.aspx?id=1&disp=2"
field.InnerText = link;
batch.AppendChild(field);
Escape it: &.
string item = "<field>http://mylink.com/page.aspx?id=1&disp=2</field>";
Escape it as &. This is called HTML/XML Entities. See more information and list of others entities here and here.
The code should look like this:
string item = "<field>http://mylink.com/page.aspx?id=1&disp=2</field>"
you can use &
As others have pointed out, you can just use an & escape sequence. However, the more elegant approach is not to deal directly with the XML at all.
var doc = new XmlDocument();
var batch = doc.CreateElement("Batch");
var field = doc.CreateElement("field");
field.InnerText = "http://mylink.com/page.aspx?id=1&disp=2"
batch.Children.AppendChild(field);
No need to worry about escaping anything, this way. :)
XmlDocument doc = new XmlDocument();
XmlElement batch = doc.CreateElement("Batch");
string item = "<field>http://mylink.com/page.aspx?id=1&disp=2</field>"
batch.InnerXml = item;
If you create the element with the Xml methods it will wrap everything up nicely for you. So use the CreateElement method again and set the InnerText property of the element to your link.
Use .InnerText rather than .InnerXml, and the XmlDocument instance will do all necessary encodings for you, like automatically escaping the & to &
The .InnerXml is used when the string you have is already valid xml which is not to be escaped, which is not the case here.

Categories