reading repeat xml using xmlnode - c#

I Have XML like
<rss>
<channel>
<item>
<category domain="category" nicename="change"><![CDATA[Changing Lives]]></category>
<category domain="category" nicename="events"><![CDATA[Events]]></category>
<category domain="category" nicename="leadership"><![CDATA[Leadership]]></category>
<category domain="category" nicename="spiritual-transformation"><![CDATA[Spiritual Transformation]]></category>
</item>
<item></item>
<item></item>
</channel>
</rss>
I am trying to read category innertext(changing lives, Events, Leadership) ... using foreach condition.. but for every loop I am getting Changing Lives only.. here is my code
protected void btnImportPost_Click(object sender, EventArgs e)
{
XmlDocument doc = new XmlDocument();
string strPath = Server.MapPath("~/App_Data/willowcreekassociationblog.wordpress.xml");
doc.Load(strPath);
//Get Channel Node
XmlNode channelNode = doc.SelectSingleNode("rss/channel");
if (channelNode != null)
{
DateTime temp;
//Add NameSpace
XmlNamespaceManager nameSpace = new XmlNamespaceManager(doc.NameTable);
nameSpace.AddNamespace("excerpt", "http://wordpress.org/export/1.2/excerpt/");
nameSpace.AddNamespace("content", "http://purl.org/rss/1.0/modules/content/");
nameSpace.AddNamespace("dc", "http://purl.org/dc/elements/1.1/");
nameSpace.AddNamespace("wfw", "http://wellformedweb.org/CommentAPI/");
nameSpace.AddNamespace("wp", "http://wordpress.org/export/1.2/");
//Parse each item
foreach (XmlNode itemNode in channelNode.SelectNodes("item"))
{
//some code here
foreach (XmlNode categoryNode in itemNode.SelectNodes("category"))
{
//CMS.SiteProvider.CategoryInfo GetCate = null;
string CategoryName = itemNode.SelectSingleNode("category").InnerText;
Response.Write(#"<script language='javascript'>alert('root Document:" + CategoryName + "');</script>");
}
}
}
}

Just use
string CategoryName = categoryNode.InnerText;

The reason is that you are not writing out the InnerText of itemNode each time round the loop, instead, you are using SelectSingleNode to pull out the first match only.
Try changing your inner loop to:
foreach (XmlNode categoryNode in itemNode.SelectNodes("category"))
{
//CMS.SiteProvider.CategoryInfo GetCate = null;
//string CategoryName = itemNode.SelectSingleNode("category").InnerText; // incorrect
string CategoryName = categoryNode.InnerText;
Console.Write(CategoryName);
}

Related

Can not read values/nodes from xml using c#

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;
}
}
}
}
}
}
}

How to get attribute xml without loop c#

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 });

how to get the value from innerXMl correctly

I plan to retrieve each suggestion in array and then stroe it in to the list. I have trouble retrieve the option node data, in this pattern {aeroplane,aeroplanes, aerobian} {i}, Any kind soul can help me out with it.
XmlDocument findStringDoc = new XmlDocument();
findStringDoc.Load (Application.dataPath+ "/" + filename);
XmlNodeList nodeList = findStringDoc.SelectNodes("/results/error");
//XmlNodeList suggestionNodeList = findStringDoc.SelectNodes("/results/error/suggestions/option");
foreach(XmlNode xn in nodeList){
errorString.Add(xn["string"].InnerText);
errorType.Add(xn["type"].InnerText);
//string temp = xn["suggestion"].InnerXml;
////TODO: Retrieve suggestions here!
XmlNodeList suggestionNodeList = findStringDoc.SelectNodes("/suggestions");
foreach(XmlNode yn in suggestionNodeList){
option[suggestionNodeList.Count] = yn["option"].InnerText;
Debug.Log(yn["option"].InnerText);
}
suggestionResult.Add (option);
//Debug.Log(suggestionResult);
//XmlNodeList suggestionNodeList = findStringDoc.SelectNodes("/results/error[string='{0}']/suggestions/option",errorString[i]);
}
<results>
<error>
<string>aeroplan</string>
<description>Spelling</description>
<precontext>a</precontext>
<suggestions>
<option>aeroplane</option>
<option>aeroplanes</option>
<option>aerobian</option>
</suggestions>
<type>spelling</type>
</error>
<error>
<string>i</string>
<description>Make I uppercase</description>
<precontext></precontext>
<suggestions>
<option>I</option>
</suggestions>
<type>grammar</type>
<url>http://service.afterthedeadline.com/info.slp?text=i&tags=PRP&engine=1</url>
</error>
</results>
You can use my code below:
private static void GetSuggestionOption(string filename, string value, string optionSuggest)
{
XDocument xDoc = XDocument.Parse(filename);
var parentNode = xDoc.Descendants().Where(x => x.Value == value).Ancestors().FirstOrDefault();
var childNode = parentNode.Descendants().Where(x => x.Name == optionSuggest);
childNode.ToList().ForEach(x => Console.WriteLine(x.Value));
}
Calling: GetSuggestionOption(fileName, "aeroplan", "option");
Happy Coding!
You can use XmlDocument.SelectNodes() method passing suitable XPath string parameter to select specific element(s) from XmlDocument, for example :
public void GetSuggestionOption(string keyword)
{
XmlDocument doc = new XmlDocument();
doc.Load (Application.dataPath+ "/" + filename);
string xpath = string.Format("//error[string='{0}']/suggestions/option", keyword);
XmlNodeList optionSuggestionList = doc.SelectNodes(xpath);
foreach (XmlNode option in optionSuggestionList)
{
Debug.Log(option.InnerXml);
}
}
You can call the method this way for example : GetSuggestionOption("aeroplan")

Querying XML document

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();
}

Get innertext from XML tags?

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;

Categories