How can I get node I want from XML - c#

<?xml version="1.0" encoding="utf-8" ?>
<Root>
<Fruits>
<Fruit>hahahaha</Fruit>
</Fruits>
</Root>
If I try this code,
string[] cFruitName; int i=0;
XmlDocument a= new XmlDocument();
a.LoadXml(getXML());
foreach (XmlNode xn in a)
{
cFruitName[i] = xn.Text;
i++;
}
but I am getting null for xn.Text.
All I want is to get values of fruit, like "hahahah" in this example.
Edit
I changed my XML now.

var xml = XDocument.Parse(getXML());
var fruits = xml.Descendants("fruit").Select(n => n.Value);
Console.WriteLine(string.Join(Environment.NewLine, fruits));
prints
hahahaha
use XPath for .net 2.0 version
XmlDocument xml = new XmlDocument();
xml.LoadXml(getXML());
XmlNodeList fruits = xml.SelectNodes("//fruit");
foreach (XmlNode fruit in fruits)
{
Console.WriteLine (fruit.InnerText);
}
prints the same

Try this:
string[] cFruitName; int i=0;
XmlDocument a= new XmlDocument();
a.LoadXml(getXML());
foreach (XmlNode xn in a.Where(x=>x.Text != null))
{
cFruitName[i] = xn.Text;
i++;
}
or
string[] cFruitName; int i=0;
XmlDocument a= new XmlDocument();
a.LoadXml(getXML());
foreach (XmlNode xn in a.Where(x=>x.Name == "fruit"))
{
cFruitName[i] = xn.Text;
i++;
}

Related

How do I get a specific element in a XML document?

I have a XML file that looks like this:
<Info>
<ID>1</ID>
<Result>
<ID>2</ID>
</Result>
</Info>
I want to count how many Info/Result/ID I have in this file.
I am doing this:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("myFile.xml");
xmlNodeList MyList = xmlDoc.GetElementsByTagName("Info/Result/ID");
int totalCount = MyList.Count;
// other logic...
The method GetElementsByTagName does not find any "ID"-field.
I want to get the "ID = 2".
How do I do that?
To count all the nodes in "Info/Result/ID" path use this..
var count = xmlDoc.SelectNodes("Info/Result/ID")?.Count ?? 0;
To process these nodes
var nodes = xmlDoc.SelectNodes("Info/Result/ID");
foreach (XmlNode node in nodes) {
var idValue = node.InnerText
// do something
}
Got it working, hereĀ“s how:
public static void MyCountExample(string myXml, out int myID)
{
var stream = new MemoryStream(Encoding.UTF8.GetBytes(myXml ?? ""));
var reader = XmlReader.Create(stream);
myID= 0;
reader.IsStartElement("Info");
while (!reader.EOF)
{
if (reader.ReadToFollowing("Result"))
{
if (reader.ReadToDescendant("ID"))
{
myID++;
else
{
return somethingElse();
}
......

HasChildNodes (.Net, XmlDocument ) always reported "true"

I would like to distinguish these two cases - but HasChildNode returns in both cases "true" and the number of childNodes is 1 in both cases.
<eventid>45072</eventid>
<titles>
<title>kabel eins late news</title>
</titles>
Here ist my sample code and output.
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlString);
XmlNodeList xnList = doc.SelectNodes("/epg/programme");
foreach (XmlNode n in xnList) {
foreach (XmlNode n1 in n.ChildNodes) {
if (n1.HasChildNodes) {
AppendText($"n1 has {n1.ChildNodes.Count} ChildNodes");
foreach (XmlNode n2 in n1.ChildNodes) {
Append(41,n2.Name, n2.InnerText);
}
}
else {
// this will never called
Append(46,n1.Name, n1.InnerText);
}
}
}
<?xml version="1.0" encoding="ISO-8859-1"?>
<epg Ver="1">
<programme>
<eventid>45072</eventid>
<titles>
<title>kabel eins late news</title>
</titles>
</programme>
</epg>
Output:
n1 has 1 ChildNodes
41:#text:45072
n1 has 1 ChildNodes
41:title:kabel eins late news
Thanks to #DavidBrowne-Microsoft I have changed my code to XDocument and a little bit Linq to XML
XDocument doc = XDocument.Parse(xmlString);
var programme = doc.Descendants("programme").Select(p => p);
foreach (XElement p in programme) {
foreach (var attr in p.Attributes()){
AppendText($"{attr.Name} {attr.Value}");
}
foreach (XElement ele in p.Elements()) {
if (ele.HasElements) {
foreach (XElement child in ele.Elements()) {
AppendText($"{child.Name} {child.Value}");
}
}
else {
AppendText($"{ele.Name} {ele.Value}");
}
}
}
I found only a few beginner examples so here is this snippet for the start.

Can't figure out how to read xml data in Visual Studio C#

I'm not sure how to read out the data from a XML file.
The XML file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<Lijsten>
<Lijst>
<Titel>Discipline</Titel>
<Waardes>Elektro</Waardes>
<Waardes>Mechanisch</Waardes>
<Waardes>Civiel</Waardes>
<Waardes>Proces</Waardes>
</Lijst>
<Lijst>
<Titel>Soort</Titel>
<Waardes>Tekening</Waardes>
<Waardes>Tekst doc</Waardes>
<Waardes>Afbeelding</Waardes>
</Lijst>
<Lijst>
<Titel>Afdruk</Titel>
<Waardes>Landscape</Waardes>
<Waardes>Portrait</Waardes>
</Lijst>
<Lijst>
<Titel>Kleur</Titel>
<Waardes>Kleur</Waardes>
<Waardes>Zwart</Waardes>
</Lijst>
<Lijst>
<Titel>Kader</Titel>
<Waardes>Aanwezig</Waardes>
<Waardes>Niet aanwezig</Waardes>
</Lijst>
</Lijsten>
I'm trying to create a radio-button menu for every "Lijst".
What I've got so far(not much):
XmlTextReader reader = new XmlTextReader("iniFile.xml");
while (reader.Read())
{
while (reader.ReadToFollowing("Lijst"))
{
while (reader.ReadToFollowing("Titel"))
{
}
}
}
If you don't want to read using XElement, you can use XmlDocument and XPath
Take a look at this example, to get all titles:
XmlDocument xdoc = new XmlDocument();
xdoc.Load(#"C:\temp\inifile.xml");
XmlNodeList nodes = xdoc.SelectNodes("//Titel");
foreach (XmlNode node in nodes)
{
Console.WriteLine(node.InnerText);
}
or, to get all Lijst nodes and then iterate through them to get title and warde values
XmlDocument xdoc = new XmlDocument();
xdoc.Load(#"C:\temp\inifile.xml");
XmlNodeList nodes = xdoc.SelectNodes("//Lijst");
foreach (XmlNode node in nodes)
{
Console.WriteLine("this is List with title: " + node["Titel"].InnerText);
Console.WriteLine("it contains wardes: " + node["Titel"].InnerText);
XmlNodeList wardeNodes = node.SelectNodes("Waardes");
foreach (XmlNode wNode in wardeNodes)
{
Console.WriteLine(" - " + wNode.InnerText);
}
}
With XElement class and LinqToXML:
XElement xml = XElement.Parse(xml);
var buttons = xml.Element("Lijsten")
.Elements()
.Select(p => new { Titel = p.Element("Titel").Value })
.ToArray();

Selectnodes only get the first node

I have an XML file looking like this:
<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<row>
<Alert>warning</Alert>
<Alert2>warning</Alert2>
</row>
</data>
When I use the code below I only get the "Alert"-node. But I wan't "Alert2" as well (and so on...). What am I missing here?
using (XmlReader reader = cmd.ExecuteXmlReader())
{
string xmlFile = "";
while (reader.Read())
{
xmlFile = reader.ReadOuterXml();
}
var doc = new XmlDocument();
doc.LoadXml(xmlFile);
var nodes = doc.SelectNodes("data/row");
if (nodes == null) return columns;
var i = 0;
foreach (XmlNode node in nodes)
{
var column = node.ChildNodes[i].Name;
columns.Add(column);
i++;
}
return columns;
}
Change your loop to the equivalent of:
var doc = new XmlDocument();
doc.LoadXml(xml);
var nodes = doc.SelectNodes("data/row");
int i = 0;
foreach (XmlNode node in nodes)
{
foreach (var child in node.ChildNodes)
{
var element = (XmlElement)child;
string nodeName = element.Name;
string value = element.InnerXml;
i++;
}
}

Xml node reading for each loop

I am trying to loop through an Xml file and display the value for account in a message.
XmlNodeList nodeList = testDoc.SelectNodes("/details/row/var");
foreach (XmlNode no in nodeList)
{
XmlNode node = testDoc.SelectSingleNode("/details/row/var[#name='account']");
test.actual = node.Attributes["value"].Value;
MessageBox.Show(test.account);
}
The message box is currently displaying the first record repeatidly, how can I get to the next record?
Thanks for your input in advance.
You are repeatedly assigning node with the same element from testDoc. It is not clear what test.account is (perhaps a mistype for test.actual)?
no is the variable which will iterate the contents of nodeList - I imagine you intended to use that.
EDIT following edit of OP
Now you've shown us what nodeList is, I suspect you want to do something like this instead :
XmlNodeList nodeList = testDoc.SelectNodes("/details/row/var[#name='account']");
foreach (XmlNode no in nodeList)
{
test.actual = no.Attributes["value"].Value;
...
XmlDocument doc = new XmlDocument();
doc.Load("d:\\test.xml");
XmlNodeList node = doc.GetElementsByTagName("w:r");
foreach (XmlNode xn in node)
{
try
{
if (xn["w:t"].InnerText != null)
{
if (xn["w:t"].InnerText == "#")
{
string placeHolder = xn["w:t"].InnerText;
foreach (XmlNode a in node)
{
if (a["w:t"].InnerText != "#")
{
string placeHolder1 = a["w:t"].InnerText;
}
}
}
}
}
catch (Exception e)
{
Console.Write(e);
}
}
Here is the sample for parent node value to get information of the child nodes.here i am using the ReportItems ParentNode and Print only image child nodes.
xmldoc.Load(rdlFile);
StringBuilder sb=new StringBuilder();
XmlNode node = xmldoc.GetElementsByTagName("ReportItems")[0];
XmlNodeList list = node.ChildNodes;
atributes=new string[node.ChildNodes.Count];
int l = 0;
for (int j = 0; j < node.ChildNodes.Count; j++)
{
if (list[j].Name == "Image")
{
XmlAttributeCollection att = list[j].Attributes;
atributes[l] = att[0].Value.ToUpper();
}
l++;
}
for (int i = 0; i < node.ChildNodes.Count; i++)
{
if (searchText.Text.ToUpper() == atributes[i])
{
XmlNodeList lastlist = node.ChildNodes;
XmlNodeList endlist = lastlist[i].ChildNodes;
for (int k = 0; k < endlist.Count; k++)
{
sb.Append(endlist[k].Name+" - "+ endlist[k].InnerText);
sb.Append("\n"+"\n");
}
}
}
let me know if you have doubt..
Try this,
XmlDocument xdoc = new XDocument();
xdoc.Load("*/File/*");
string xmlcontents = xdoc.InnerXml;
var xpath = "(/details/row/var[#name='account'])";
XmlNodeList lists = xdoc.DocumentElement.SelectNodes(xpath);
foreach (XmlNode _node in lists)
{
string _nodeValue = _node.InnerText;
MessageBox.Show(_nodeValue);
}
Try the following:
//Create an xml reader;
XmlDocument _xmlDocument = new XmlDocument();
_xmlDocument.Load(/*File Name here*/);
//Select the element with in the xml you wish to extract;
XmlNodeList _nodeList = _xmlDocument.SelectNodes("/details/row/var[#name='account']");
//Display the values in the node list to the screen;
foreach (XmlNode _node in _nodeList)
{
String _nodeValue = _node.InnerText.ToString();
MessageBox.Show(_nodeValue.ToString());
}
I'm not 100% sure, but you may need to use recursion. If not, it should just look like this:
XmlDocument doc = //etc..
foreach(XmlNode node in doc.ChildNodes)
{
if(node.Name == "account")
{
MessageBox.Show(node.Value);
}
}
You shouldn't spend time with reading the xml node by node. Try Deserialization:

Categories

Resources