I am working on my project, I am totally new to C# and I need to use C# to do my work. I really hope you guys can lend me a hand in the below issue. Your help will be very much appreciated!! Thanks.
I have an XML file which has two <item>...</item> in parent <channel>. I executed my code, what I get is only as below - data of one <item> appeared:
Title: Re: My view of Tesco
Desciption: Stay clear of the iii IPO when it comes onto the market.
3 quarters are multiples, triples, quadrupole, W-T-F. It´s like ebay
a lot bidding there, is fake too.
Today´s thought of the day: Odd is that Deloitte seems to have
escaped headlines. Accusation it colluded with Standard Chartered on
regulatory report cd be Enron moment Remember those old accountants
Deloitte, Mr. Hyman (RBS)? By Hardcore Uproar
Date: Tue, 07 Aug 2012 14:03:00 GMT
Author: Hardcore Uproar
My code is as below:
private void btnComSearch_Click(object sender, EventArgs e)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("tsco.xml");
XmlElement root = xmlDoc.DocumentElement;
XmlNodeList nodes = root.SelectNodes("item");
foreach (XmlNode node in nodes)
{
XmlNodeList comTitle = xmlDoc.GetElementsByTagName("title");
XmlNodeList comDesc = xmlDoc.GetElementsByTagName("description");
XmlNodeList comDate = xmlDoc.GetElementsByTagName("pubDate");
XmlNodeList comAuthor = xmlDoc.GetElementsByTagName("creator");
StringBuilder sb = new StringBuilder();
sb.AppendLine("Title: " + comTitle[0].InnerText + "\n");
sb.AppendLine("Desciption: " + comDesc[0].InnerText + "\n");
sb.AppendLine("Date: " + comDate[0].InnerText + "\n");
sb.AppendLine("Author: " + comAuthor[0].InnerText + "\n" + "---------------" + "\n");
richComResults.Text = sb.ToString();
}
}
My XML file:
<channel>
<item>
<title>Re: My view of Tesco</title>
<description>
<![CDATA[ Stay clear of the iii IPO when it comes onto the market. 3 quarters are multiples, triples, quadrupole, W-T-F. It´s like ebay a lot bidding there, is fake too.Today´s thought of the day: Odd is that Deloitte seems to have escaped headlines. Accusation it colluded with Standard Chartered on regulatory report cd be Enron moment Remember those old accountants Deloitte, Mr. Hyman (RBS)? By Hardcore Uproar ]]>
</description>
<pubDate>Tue, 07 Aug 2012 14:03:00 GMT</pubDate>
<creator>Hardcore Uproar</creator>
</item>
<item>
<title></title>
<description>
<![CDATA[ Raw material inflation;
Rising (relative)
wealth outside of EU.
Increased global demand for agri-commodities due to increasing population and relative wealth of Eastern countries.
Decoupling of subsidy from agri-production = bad for supermarkets.
Weather problems, diminished /(ing) resources and a general plateau reached in agriculture in terms of yield achievable = limited supply.
Over supply of supermarkets/ retailers (too much choice= supply>demand)
Diminished disposable income;
General recession.
Poor pension performance.
Over indebtidness in UK (further compounded by any increases in interest rates required to curb inflation).
All this is bad news for supermarkets.. in my locality in a farily small town of 14,000 people we have a large ASDA, huge TESCO and M and S and numerous discounters.. they must be counting on all 14000 of those people visiting ALL of their local supermarkets at least 9 times a week IMHO!!
By t8vet ]]>
</description>
<pubDate>Mon, 06 Aug 2012 18:47:00 GMT</pubDate>
<creator>t8vet</creator>
</item>
</channel>
My Edited Code after applying your (horgh) codes:
private void btnComSearch_Click(object sender, EventArgs e)
{
XmlDocument xmlDoc = new XmlDocument(); //* create an xml document object.
xmlDoc.Load("tsco.xml"); //* load the XML document from the specified file.
XmlElement root = xmlDoc.DocumentElement;
XmlNodeList nodes = root.SelectNodes("item"); // You can also use XPath here
foreach (XmlNode node in nodes)
{
StringBuilder sb = new StringBuilder();
foreach (XmlNode child in node.ChildNodes)
sb.AppendLine(string.Format("{0}:\t{1}", child.Name, child.FirstChild == null ? string.Empty : child.FirstChild.Value));
richComResults.Text = sb.ToString();
}
Console.ReadLine();
}
I am totally lost. I tried looking through the websites and also those were asking similar questions, but I don't really understand and I tried they don't work in my situation. I am not sure what have I done wrongly. Your help would be much appreciated :) Thank you so much.
You are watching a xmlDoc, while you should watch each node. Try this:
XmlDocument xmlDoc = new XmlDocument(); //* create an xml document object.
xmlDoc.Load("tsco.xml"); //* load the XML document from the specified file.
richComResults.Text = string.Empty;
XmlElement root = xmlDoc.DocumentElement;
XmlNodeList nodes = root.SelectNodes("item"); // You can also use XPath here
StringBuilder sb = new StringBuilder();
foreach (XmlNode node in nodes)
{
foreach (XmlNode child in node.ChildNodes)
sb.AppendLine(string.Format("{0}:\t{1}", child.Name, child.FirstChild == null ? string.Empty : child.FirstChild.Value));
}
richComResults.Text = sb.ToString();
Related
<Report xmlns="Microsoft.SystemCenter.DataWarehouse.Report.Alert" xmlns:p1="w3.org/2001/XMLSchema-instance"; Name="Microsoft.SystemCenter.DataWarehouse.Report.Alert" p1:schemaLocation="Microsoft.SystemCenter.DataWarehou?Schema=True">
<Title>Alert Report</Title>
<Created>6/27/2013 9:32 PM</Created>
<StartDate>6/1/2013 9:29 PM</StartDate>
<EndDate>6/27/2013 9:29 PM</EndDate>
<TimeZone>(UTC)</TimeZone>
<Severity>Warning, Critical</Severity>
<Priority>Low, Medium, High</Priority>
<AlertTable>
<Alerts>
<Alert>
<AlertName></AlertName>
<Priority></Priority>
</Alert>
</Alerts>
</AlertTable>
</Report>
So I'm trying to pull down the list of nodes that appear under Alerts child. So /Report/AlertTable/Alerts.
I've done very similar before but in this format it is not working for some reason. Can someone point me out in the right direction?
XmlDocument Log = new XmlDocument();
Log.Load("test.xml");
XmlNodeList myLog = Log.DocumentElement.SelectNodes("//Report/AlertTable/Alerts");
foreach (XmlNode alert in myLog)
{
Console.Write("HERE");
Console.WriteLine(alert.SelectNodes("AlertName").ToString());
Console.WriteLine(alert.SelectNodes("Priority").ToString());
Console.Read();
}
EDIT:
One of the responses had me try to use a bunch of namespace with p1 but had no such luck.
EDIT:
Did not work either:
var name = new XmlNamespaceManager(log.NameTable);
name.AddNamespace("Report", "http://www.w3.org/2001/XMLSchema-instance");
XmlNodeList xml = log.SelectNodes("//Report:Alerts", name);
From a site:
nodename Selects all nodes with the name "nodename"
/ Selects from the root node
// Selects nodes in the document from the current node that match the selection no matter where they are
So I believe
"/AlertTable/Alerts"
would work, as that would be 'from the root node' as well as
"Report/AlertTable/Alerts"
XPath Site
Figured this sucker out.
It had to do with the namespace of "Microsoft.SystemCenter.DataWarehouse.Report.Alert". Changing this to anything but that won't read the XML properly.
XmlDocument log = new XmlDocument();
log.Load(#"C:\Users\barranca\Desktop\test.xml");
// XmlNodeList xml = log.SelectNodes("//ns1:Alerts");
var name = new XmlNamespaceManager(log.NameTable);
name.AddNamespace("ns1", "Microsoft.SystemCenter.DataWarehouse.Report.Alert");
XmlNodeList xml = log.SelectNodes("//ns1:Alert", name);
foreach (XmlNode alert in xml)
{
Console.Write("HERE");
XmlNode test = alert.SelectSingleNode("//ns1:AlertName",name);
string testing = test.InnerText;
Console.Write(testing);
}
Good Evening All, and happy weekend!.
I have been trying all day to understand how to parse my simple XML file so I can understand it enough to write a personal project I want to work on.
I have been reading articles on this site and others but cannot get past where I am :(
My XML Document is ...
<XML>
<User>
<ID>123456789</ID>
<Device>My PC</Device>
</User>
<History>
<CreationTime>27 June 2013</CreationTime>
<UpdatedTime>29 June 2013</UpdatedTime>
<LastUsage>30 June 2013</LastUsage>
<UsageCount>103</UsageCount>
</History>
<Configuration>
<Name>Test Item</Name>
<Details>READ ME</Details>
<Enabled>true</Enabled>
</Configuration>
</XML>
I am trying to get the value in the details element (READ ME). Below is my code
// Start Logging Progress
Console.WriteLine("Test Application - XML Parsing and Creating");
Console.ReadKey();
// Load XML Document
XmlDocument MyDoc = new XmlDocument(); MyDoc.Load(#"E:\MyXML.XML");
// Select Node
XmlNode MyNode = MyDoc.SelectSingleNode("XML/Configuration/Details");
// Output Node Value
Console.WriteLine(String.Concat("Details: ", MyNode.Value));
// Pause
Console.ReadKey();
My console application is running and outputing "Target: " but not giving me the detail within the element.
Can somebody see why this is happening, and perhaps give me advice if I am completely off the wheel? I have no previous knowledge in reading XML files; hence where I am now :)
Thanks! Tom
With the your XPATH expression
// Select Node
XmlNode MyNode = MyDoc.SelectSingleNode("XML/Configuration/Details");
your are selection an element so the type of the MyNode will be XmlElement but the Value of an XmlElement is always null (see on MSDN) so you need to use XmlElement.InnerText or XmlElement.InnerXml isntead.
So the changed your code to
// Output Node Value
Console.WriteLine(String.Concat("Details: ", MyNode.InnerText));
Or you can select the content of an element with using the XPATH text() function, in this case MyNode will be XmlText where you get its value with Value:
// Select Node
XmlNode MyNode = MyDoc.SelectSingleNode("XML/Configuration/Details/text()");
// Output Node Value
Console.WriteLine(String.Concat("Details: ", MyNode.Value));
As a sidenote if you are anyway learning XML manipulation in C# you should check out LINQ to XML which is another/newer way to working with XML in C#.
Just for interest, a little-known "simple" syntax is this:
XmlDocument myDoc = new XmlDocument();
myDoc.Load(#"D:\MyXML.XML");
string details = myDoc["XML"]["Configuration"]["Details"].InnerText;
Note that this (and the XPath approach) could go pop if your XML doesn't conform to the structure you're expecting, so you'd ideally put some validation in there as well.
U can use Xpath library for that (u must include "System.Xml.XPath"):
XmlDocument document = new XmlDocument();
document.Load("MyXml.xml");
XPathNavigator navigator = document.CreateNavigator();
foreach (XPathNavigator nav in navigator.Select("//Details"))
{
Console.WriteLine(nav.Value);
}
the above code iterate over every node called (Details) extracting information and print it.
If you want to retrieve a particular value from an XML file
XmlDocument _LocalInfo_Xml = new XmlDocument();
_LocalInfo_Xml.Load(fileName);
XmlElement _XmlElement;
_XmlElement = _LocalInfo_Xml.GetElementsByTagName("UserId")[0] as XmlElement;
string Value = _XmlElement.InnerText;
Value contains the text value
Okay, silly question here, but I'm just starting with xml.
<fifth points = '500' answer = 'Ada Lovelace'>
This woman, known as the world's first computer programmer
was also a Countess.
</fifth>
How exactly do I get at the data after Ada Lovelace? I understand that fifth is the node, and that points and answer are the attributes. What must I grab to get the desired data?
here is something you can try and test to help you understand how to get at the node.InnerText
var testDoc =
#"<fifth points = '500' answer = 'Ada Lovelace'>"
+ "This woman, known as the world's first computer programmer "
+ "was also a Countess."
+ "</fifth>";
XmlDocument docXML = new XmlDocument();
docXML.LoadXml(testDoc);
var innerxml = docXML.InnerText;
MessageBox.Show(innerxml);
You're probably looking for something like:
node.InnerText
To learn about parsing nodes XML in C#, read up on http://www.csharp-examples.net/xml-nodes-by-name/ . This post, http://www.codeproject.com/Articles/7718/Using-XML-in-C-in-the-simplest-way may also be helpful as well, as it provides some of the simplest ways of parsing XML in C#.
You can simply index XmlNode with the node name: xmlNode["FirstName"].InnerText. See the example below.
XmlDocument xml = new XmlDocument();
// suppose that myXmlString contains "<Names>...</Names>":
xml.LoadXml(myXmlString);
XmlNodeList xnList = xml.SelectNodes("/Names/Name");
foreach (XmlNode xn in xnList)
{
string firstName = xn["FirstName"].InnerText;
string lastName = xn["LastName"].InnerText;
Console.WriteLine("Name: {0} {1}", firstName, lastName);
}
The output is:
Name: John Smith Name: James White
Edit: It's important to note that DJ KRAZE and Jeremy Thompson also inspired my answer.
You can use Linq to Xml. If this is a full xml you need to parse:
var xml = "<fifth points='500' answer='Ada Lovelace'>This woman, known as the world's first computer programmer was also a Countess.</fifth>";
XElement element = XElement.Parse(xml);
string text = (string)element; // takes element's innerText
If you need to select this element from your xml file by answer attribute value:
XDocument xdoc = XDocument.Load(path_to_xml_file);
string text = xdoc.Descendants("fifth")
.Where(e => (string)e.Attribute("answer") == "Ada Lovelace")
.Select(e => (string)e)
.FirstOrDefault(); // returns first matched element or null
I'm using a CMS and found a function to generate a rss feed from content within folders. However I would like one of the rows removing from the list. I've done my research and I 'think' I should be using XmlDocument class to help me remove the row I don't want. I've used Firebug and FirePath to get the XPath - but I cant seem to figure out how to apply it appropriately. I am also uncertain of whether I should be using .Load or .LoadXml - I've used the latter seing as though the feed displays fine. However I have had to convert ToString() to get rid of that overloaded match error....
The row I want removing is called "Archived Planes"
The XPath I get for FirePath is ".//*[#id='feedContent']/xhtml:div[11]/xhtml:h3/xhtml:a"
I am also assuming that .RemoveChild(node); will remove it out of rssData before I Response.Write. Thanks
Object rssData = new object();
Cms.UI.CommonUI.ApplicationAPI AppAPI = new Cms.UI.CommonUI.ApplicationAPI();
rssData = AppAPI.ecmRssSummary(50, true, "DateCreated", 0, "");
Response.ContentType = "text/xml";
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(rssData.ToString());
XmlNode node = xmlDocument.SelectSingleNode(#"xhtml:div/xhtml:h3/xhtml[a = 'Archived Planes']");
if (node != null)
{
node.ParentNode.RemoveChild(node);
}
Response.Write(rssData);
Edited to include output below
This is the what the response.write from rssData is pumping out:
<?xml version="1.0" ?>
<rss xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0">
<channel>
<title>Plane feed</title>
<link>http://www.domain.rss1.aspx</link>
<description></description>
<item>
<title>New Planes</title>
<link>http://www.domainx1.aspx</link>
<description>
This is the description
</description>
<author>Andrew</author>
<pubDate>Thu, 16 Aug 2012 15:55:53 GMT</pubDate>
</item>
<item>
<title>Archived Planes</title>
<link>http://www.domain23.aspx</link>
<description>
Description of Archived Planes
</description>
<author>Jan</author>
<pubDate>Wed, 15 Aug 2012 10:34:23 GMT</pubDate>
</item>
</channel>
</rss>
I suspect your xpath is incorrect, it looks like some funky dom element that you are referencing and not the xml element... e.g. for the following xml
<?xml version="1.0" encoding="UTF-16" standalone="yes"?>
<NewDataSet>
<userinfo>
<username>pqr2</username>
<pass>abc</pass>
<addr>abc</addr>
</userinfo>
<userinfo>
<username>pqr1</username>
<pass>pqr2</pass>
<addr>pqr3</addr>
</userinfo>
</NewDataSet>
This code will remove the userinfo node with an username element of pqr1
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(#"file.xml");
XmlNode node = xmlDocument.SelectSingleNode(#"NewDataSet/userinfo[username = 'pqr1']");
if (node != null) {
node.ParentNode.RemoveChild(node);
xmlDocument.Save(#"file.xml");
}
Thought I would post the answer, although I'll mark Pauls as the answer, as his code/advice was the basis of this and my further research. Still don't know what the '#' in SelectSingleNode is and whether I should really have it - will do more research.
Object rssData = new object();
Cms.UI.CommonUI.ApplicationAPI AppAPI = new Cms.UI.CommonUI.ApplicationAPI();
rssData = AppAPI.ecmRssSummary(50, true, "DateCreated", 0, "");
Response.ContentType = "text/xml";
Response.ContentEncoding = System.Text.Encoding.UTF8;
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(rssData.ToString());
XmlNode node = xmlDocument.SelectSingleNode("rss/channel/item[title = 'Archived Planes']");
if (node != null)
try
{
node.ParentNode.RemoveChild(node);
xmlDocument.Save(Response.Output);
}
catch { }
else { Response.Write(rssData); }
}
The # symbol is simply to denote a verbatim string literal (allows you to have funky characters in the string compared to the normal string declaration) e.g.
string e = "Joe said \"Hello\" to me"; // Joe said "Hello" to me
string f = #"Joe said ""Hello"" to me"; // Joe said "Hello" to me
See this msdn link for more info
I try many different solution on this site and none seems to work for me .
I getting a xml file from a website and it's returned to me in a string.
using the code below I need to read the nodes in the "entry" section of the xml file.
but it always comes up "0" meaning no nodes found. the only thing left I think is the XML file is not correct?
any help would be great...
------------------code below ------------:
//gets the xml file
string WeatherXML = HttpPost("http://weather.gov/alerts-beta/wwaatmget.php?x=MIC159", "");
//create a xmldoc object..
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
//load the object with the xml file from the web...
doc.LoadXml(WeatherXML);
//go to the main node..
XmlNodeList nodes = doc.SelectNodes("/feed/entry");
//I also tried ....
//doc.SelectNodes("//feed/entry");
//doc.SelectNodes("/entry");
//doc.SelectNodes("//entry");
//loop through the nodes (here is where the nodelist is always empty..
foreach (XmlNode node in nodes)
{
string msgType = node["cap:msgType"].InnerText;
string areaDesc = node["cap:areaDesc"].InnerText;
string summary = node["summary"].InnerText;
string title = node["title"].InnerText;
string link = node["link"].InnerText;
}
------------------------------XML file below------------------
<?xml version = '1.0' encoding = 'UTF-8' standalone = 'no'?>
<!--
This atom/xml feed is an index to active advisories, watches and warnings issued
by the National Weather Service. This index file is not the complete Common
Alerting Protocol (CAP) alert message. To obtain the complete CAP alert,
please follow the links for each entry in this index. Also note the CAP
message uses a style sheet to convey the information in a human readable
format. Please view the source of the CAP message to see the complete data
set. Not all information in the CAP message is contained in this index of
active alerts.
-->
<feed
xmlns = 'http://www.w3.org/2005/Atom'
xmlns:cap = 'urn:oasis:names:tc:emergency:cap:1.1'
xmlns:ha = 'http://www.alerting.net/namespace/index_1.0'
>
<!-- http-date = Sun, 22 Aug 2010 07:06:00 GMT -->
<id>http://www.weather.gov/alerts-beta/wwaatmget.php?x=MIC159</id>
<generator>
NWS CAP Server
</generator>
<updated>2010-08-22T19:06:00-04:00</updated>
<author>
<name>
w-nws.webmaster#noaa.gov
</name>
</author>
<title>
Current Watches, Warnings and Advisories for Van Buren (MIC159) Michigan Issued by the National Weather Service
</title>
<link href='http://www.weather.gov/alerts-beta/wwaatmget.php?x=MIC159'/>
<entry>
<id>http://www.weather.gov/alerts-beta/wwacapget.php?x=MI20100822190600IWXRipCurrentStatementIWX20100823060000MI</id>
<updated>2010-08-22T15:06:00-04:00</updated>
<published>2010-08-22T15:06:00-04:00</published>
<author>
<name>w-nws.webmaster#noaa.gov</name>
</author>
<title>Rip Current Statement issued August 22 at 3:06PM EDT expiring August 23 at 2:00AM EDT by NWS NorthernIndiana http://www.crh.noaa.gov/iwx/</title>
<link href="http://www.weather.gov/alerts-beta/wwacapget.php?x=MI20100822190600IWXRipCurrentStatementIWX20100823060000MI"/>
<summary>...RIP CURRENT RISK REMAINS IN EFFECT UNTIL 2 AM EDT /1 AM CDT/ MONDAY... ...HIGH RISK OF RIP CURRENTS... HIGH WAVES ALONG THE SHORELINE WILL BRING AN INCREASED RISK OF RIP CURRENTS INTO THE EARLY MORNING HOURS OF MONDAY...CREATING DANGEROUS SWIMMING CONDITIONS.</summary>
<cap:effective>2010-08-22T15:06:00-04:00</cap:effective>
<cap:expires>2010-08-23T02:00:00-04:00</cap:expires>
<cap:status>Actual</cap:status>
<cap:msgType>Alert</cap:msgType>
<cap:category>Met</cap:category>
<cap:urgency></cap:urgency>
<cap:severity></cap:severity>
<cap:certainty></cap:certainty>
<cap:areaDesc>Berrien; Cass; La Porte; St. Joseph; Van Buren</cap:areaDesc>
<cap:geocode>
<valueName>FIPS6</valueName>
<value>018091 018141 026021 026027 026159</value>
</cap:geocode>
<cap:parameter>
<valueName>VTEC</valueName>
<value>/O.CON.KIWX.RP.S.0017.000000T0000Z-100823T0600Z/</value>
</cap:parameter>
</entry>
</feed>:"
It’s because your XML root node has a namespace. The following should work:
//load the object with the xml file from the web...
doc.LoadXml(WeatherXML);
XmlNamespaceManager nsMgr = new XmlNamespaceManager(doc.NameTable);
nsMgr.AddNamespace("m", "http://www.w3.org/2005/Atom");
//go to the main node..
XmlNodeList nodes = doc.SelectNodes("m:feed", nsMgr);
Console.WriteLine(nodes.Count); // outputs 1
Add the "http://www.w3.org/2005/Atom" namespace to the XPath using an XmlNamespaceManager.
Instead of using regular System.Xml classes you could also use classes from the System.Xml.Linq namespace. Personally I find these a lot easier to use.
var doc = XDocument.Parse(WeatherXml);
var entryNodes = doc.Descendants(
XName.Get("entry", "http://www.w3.org/2005/Atom"));
This will give you a collection of entry nodes from the document.