I am currently using the code
string[] toSearch = { "title", "link", "description" };
string url = "http://www.ebay.co.uk/sch/i.html?_sacat=0&_from=R40&_nkw=" + itemToSearch.Replace(" ", "+") + "&_sop=15&_rss=1";
WebRequest request = WebRequest.Create(url);
WebResponse responce = request.GetResponse();
Stream rssStream = responce.GetResponseStream();
XmlDocument rssDocument = new XmlDocument();
rssDocument.Load(rssStream);
XmlNodeList rssItems = rssDocument.SelectNodes("channel/item");
int xMax = toSearch.Length;
int yMax = rssItems.Count;
String[,] tempRssData = new String[yMax + 1, xMax];
for (int i = 0; i < rssItems.Count; ++i)
{
XmlNode rssNode = null;
for (int ii = 0; ii < toSearch.Length; ++ii)
{
rssNode = rssItems.Item(i).SelectSingleNode(toSearch[ii]);
if (rssNode != null)
{
tempRssData[i, ii] = rssNode.InnerText;
}
else
{
tempRssData[i, ii] = "";
}
}
}
but rssItems.Count = 0, Does anyone know why.
the example of the rss feed I am using is
http://www.ebay.co.uk/sch/i.html?_sacat=0&_from=R40&_nkw=raspberry+pi&_sop=15&_rss=1
Your XPath is wrong.
I would suggest you learn how to use XPath correctly by inspecting the XPath spec and looking at tutorials online.
To fix the problem, you will need to change:
XmlNodeList rssItems = rssDocument.SelectNodes("channel/item");
to:
XmlNodeList rssItems = rssDocument.SelectNodes("//channel/item");
You can also execute XPath queries natively in Chrome. Open your RSS feed page in Chrome, open the Developer Tools, open the Console and type in:
$x("expression")
so it becomes:
$x("channel/item")
Which, you should notice, returns nothing.
Related
remcl3.Wcl3Client client = new remcl3.Wcl3Client();
string rrs = client.getsql("sabatini", "ZXCqwe1920",112, w);
string xml = #rrs;
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
XmlNodeList elemList = doc.GetElementsByTagName("AC_NO");
XmlNodeList elem = doc.GetElementsByTagName("AC_NAME");
for (int i = 0; i < elemList.Count; i++)
{
rem_no.DataTextField = doc.GetElementsByTagName("AC_NO").ToString();
rem_no.Items.Add(elemList[i].InnerXml);
rem_no.DataValueField = doc.GetElementsByTagName("AC_NAME").ToString();
rem_no.Items.Add(elem[i].InnerXml);
}
I'm trying to parse XML with two fields ac_no, ac_name using C# ASP.NET and put the data value, data text for the dropdownlist and bind the data value.
I have tried the following code but with no luck:
I want to bind the ac_no and show the ac_name; any help?
You can use a DataTable:
C# Code:
remcl3.Wcl3Client client = new remcl3.Wcl3Client();
string rrs = client.getsql("sabatini", "ZXCqwe1920",112, w);
string xml = #rrs;
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
XmlNodeList elemList = doc.GetElementsByTagName("AC_NO");
XmlNodeList elem = doc.GetElementsByTagName("AC_NAME");
DataTable table = new DataTable();
table.Columns.Add("AC_NO");
table.Columns.Add("AC_NAME");
for (int i = 0; i < elemList.Count; i++)
{
DataRow row = table.NewRow();
var value = elemList[i].InnerXml;
var text = elem[i].InnerXml;
row["AC_NO"] = value;
row["AC_NAME"] = text;
table.Rows.Add(row);
}
// Configure your Dropdownlist
rem_no.DataSource = table;
rem_no.ValueMember = "AC_NO";
rem_no.DisplayMember = "AC_NAME";
rem_no.SelectedIndex = -1;
Or use a ListItem:
C# Code:
remcl3.Wcl3Client client = new remcl3.Wcl3Client();
string rrs = client.getsql("sabatini", "ZXCqwe1920",112, w);
string xml = #rrs;
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
XmlNodeList elemList = doc.GetElementsByTagName("AC_NO");
XmlNodeList elem = doc.GetElementsByTagName("AC_NAME");
for (int i = 0; i < elemList.Count; i++)
{
var value = elemList[i].InnerXml;
var text = elem[i].InnerXml;
rem_no.Items.Add(new ListItem(text, value));
}
Im trying to create a XML file with the next structure
<tdes1></tdes1>
<tdes2></tdes2>
<tdes3></tdes3>
but i am getting error when trying to append the elemnt
This is what i was trying to do
var xmlLlavesTDES = new XmlDocument();
xmlLlavesTDES.AppendChild(xmlLlavesTDES.CreateXmlDeclaration("1.0", "UTF-8", null));
// XElement test = new XElement("test");
for (var i = 0; i < this.llavesTDESArray.Length; i++)
{
var llavesTDESEncriptadas = encriptador.Encriptar(this.llavesTDESArray[i], this.llavePublicaEsclavo);
var llaveNum = i + 1;
XmlElement nodo= xmlLlavesTDES.CreateElement("tdes" + llaveNum);
nodo.InnerText = llavesTDESEncriptadas;
xmlLlavesTDES.AppendChild(nodo);
}
The error I get is This document already has a 'DocumentElement' node
i recommend an aproach similar to this using Linq instead of your approach:
//using System.Xml.Linq;
var xmlLlavesTDES = new XDocument();
XElement rootElement = new XElement("AllMyValues");
for (var i = 0; i < this.llavesTDESArray.Length; i++)
{
var llavesTDESEncriptadas = encriptador.Encriptar(this.llavesTDESArray[i], this.llavePublicaEsclavo);
var llaveNum = i + 1;
XElement nodo = new XElement("tdes" + llaveNum);
nodo.Value = llavesTDESEncriptadas;
rootElement.Add(nodo);
}
xmlLlavesTDES.Add(rootElement);
my code attempts to grab data from the RSS feed of a website. It grabs the nodes fine, but when attempting to grab the data from a node with a colon, it crashes and gives the error "Namespace Manager or XsltContext needed. This query has a prefix, variable, or user-defined function." The code is shown below:
WebRequest request = WebRequest.Create("http://buypoe.com/external.php?type=RSS2&lastpost=true");
WebResponse response = request.GetResponse();
StringBuilder sb = new StringBuilder("");
System.IO.StreamReader rssStream = new System.IO.StreamReader(response.GetResponseStream(), System.Text.Encoding.GetEncoding("utf-8"));
XmlDocument rssDoc = new XmlDocument();
rssDoc.Load(rssStream);
XmlNodeList rssItems = rssDoc.SelectNodes("rss/channel/item");
for (int i = 0; i < 5; i++)
{
XmlNode rssDetail;
rssDetail = rssItems.Item(i).SelectSingleNode("dc:creator");
if (rssDetail != null)
{
user = rssDetail.InnerText;
}
else
{
user = "";
}
}
I understand that I need to define the namespace, but am unsure how to do this. Help would be appreciated.
You have to declare the dc namespace prefix using an XmlNamespaceManager before you can use it in XPath expressions:
XmlDocument rssDoc = new XmlDocument();
rssDoc.Load(rssStream);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(rssDoc.NameTable);
nsmgr.AddNamespace("dc", "http://purl.org/dc/elements/1.1/");
XmlNodeList rssItems = rssDoc.SelectNodes("rss/channel/item");
for (int i = 0; i < 5; i++) {
XmlNode rssDetail = rssItems[i].SelectSingleNode("dc:creator", nsmgr);
if (rssDetail != null) {
user = rssDetail.InnerText;
} else {
user = "";
}
}
I have a Xamarin (C#) project, where I am trying to loop through some XML, but for some reason my code is not working.
This is what I have now:
DeviceList = new List<DeviceInfo>();
string ResultStatus = "";
string ResultDevice = "";
var result = Encoding.Default.GetString(e.Result);
result = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + result;
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(result);
string xPathStatus = "ed_listdevices";
var nodes = xmlDoc.SelectNodes(xPathStatus);
foreach (XmlNode xNode in nodes) {
ResultStatus = xNode.SelectSingleNode("//status").InnerText;
ResultDevice = xNode.SelectSingleNode("//device").InnerText;
}
if (ResultStatus.ToLower() == "ok") {
XmlDocument deviceDoc = new XmlDocument();
deviceDoc.LoadXml(result);
var deviceNodes = deviceDoc.SelectNodes(xPathStatus + "/device");
//foreach(XmlNode dNode in deviceNodes) {
for (int i = 0; i < deviceNodes.Count; i++) {
DeviceList.Add(new DeviceInfo() {
DeviceID = deviceNodes[i].SelectSingleNode("//id").InnerXml,
DeviceName = deviceNodes[i].SelectSingleNode("//name").InnerXml,
DeviceExtraName = "",
DeviceOnlineStatus = deviceNodes[i].SelectSingleNode("//status").InnerXml,
Location = deviceNodes[i].SelectSingleNode("//address").InnerXml,
Time = deviceNodes[i].SelectSingleNode("//time").InnerXml
});
}
}
When I step though the code I get the "ResultStatus" and "ResultDevice" correctly, and when I get to the
for (int i = 0; i < deviceNodes.Count; i++)
the "deviceNodes" variable have a count of 91, and I can see all the individual xml elements that I am suppose to get from the webservice I am calling.
However, when I loop through deviceNodes[i] I only get values from the very first XML element (yes, the value of "i" does change). In other words, my DeviceList is filled with 91 entries with the same values.
Am I missing something obvious?? What am I doing wrong since this isn't working??
PS: I have also tried using a foreach (XmlNode node in deviceNodes) but the result was the same.
"//" in the selector tells it to search from the root node of the document. If you want to search locally under the "current" node, remove the "//"
This is my first time attempting to parse XML using C# and feel like I'm running in circles right now. I am calling a WCF web service which, based upon user input, conducts a search through a database against company names. It returns the results in an XML document with each entry formatted as it is below.
Given this XML structure, how would I go about obtaining the values for the d:AccountId and d:Name nodes using C#?
<entry>
<id></id>
<title type=\"text\"></title>
<updated></updated>
<author><name /></author>
<link rel=\"edit\" title=\"Account\" href=\"AccountSet\" />
<category term=\"Microsoft.Crm.Sdk.Data.Services.Account\" scheme=\"http://schemas.microsoft.com/ado/2007/08/dataservices/scheme\" />
<content type=\"application/xml\">
<m:properties>
<d:neu_UniqueId></d:neu_UniqueId>
<d:AccountId m:type=\"Edm.Guid\"></d:AccountId>
<d:Name></d:Name>
</m:properties></content>
</entry>
Here is my first attempt. The program threw an exception at the node3 variable.
try
{
WebRequest myWebRequest = WebRequest.Create(URL);
myWebRequest.PreAuthenticate = true;
myWebRequest.Credentials = System.Net.CredentialCache.DefaultCredentials;
//myWebRequest.Headers.Add("Access-Control-Allow-Origin", url);
WebResponse myWebResponse = myWebRequest.GetResponse();
Stream myFileStreamResult = myWebResponse.GetResponseStream();
Encoding encoder = System.Text.Encoding.GetEncoding("utf-8");
StreamReader readStream = new StreamReader(myFileStreamResult, encoder);
results = readStream.ReadToEnd();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(results);
XmlNodeList parentNode = xmlDoc.GetElementsByTagName("entry");
foreach (XmlNode childNode in parentNode)
{
string node = childNode.ToString();
string node2 = childNode.Value;
string node3 = childNode.Attributes["title"].Value;
string node7 = childNode.Attributes["m:properties"].Value;
string node8 = childNode.Attributes["m:properties\\d:AccountId"].Value;
string node9 = childNode.Attributes["m:properties\\d:Name"].Value;
string node10 = childNode.Attributes["m:properties\\d:AccountId"].Value;
}
}
Assuming the API reliably returns that XML structure you can simply specify the path to the node as "/entry/m:properties" then call get children. After that you'll want to loop over those nodes, checking for the nodes you want.
Currently your foreach loop is attempting all of those operations on the <id></id> node which causes an Exception because there is no "title" attribute.
So to give some sample code, you're looking for something like this;
XmlNode props = root.SelectSingleNode("/entry/m:properties");
for (int i = 0; i < props.ChildNodes.Count; i++)
{
if (propes.ChildNodes[i].Name = "node I want")
{
//do something
}
}
Or if you specifically only want those two values, then just use SelectSingleNode with the full path to that node. From your question it sounds like there is no reason to use iteration. So you could simply do;
string accountName = root.SelectSingleNode("/entry/m:properties/d:Name").InnerXml;
to get the account name.
using Linq2Xml will probably be a little easier.
var xml = "<entry xmlns:m=\"ns1\" xmlns:n=\"ns2\" xmlns:d=\"ns3\">" +
"<id></id>" +
"<title type=\"text\"></title>" +
"<updated></updated>" +
"<author><name /></author>" +
"<link rel=\"edit\" title=\"Account\" href=\"AccountSet\" />" +
"<category term=\"Microsoft.Crm.Sdk.Data.Services.Account\" scheme=\"http://schemas.microsoft.com/ado/2007/08/dataservices/scheme\" />" +
"<content type=\"application/xml\">" +
"<m:properties>" +
"<d:neu_UniqueId></d:neu_UniqueId>" +
"<d:AccountId m:type=\"Edm.Guid\">Account ID</d:AccountId>" +
"<d:Name>Account Name</d:Name>" +
"</m:properties></content>" +
"</entry>";
const string namespaceM = "ns1";
const string namespaceD = "ns3";
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
{
using (var reader = XmlReader.Create(stream))
{
var document = XDocument.Load(reader, LoadOptions.None);
var contentNode = document.Elements().First().Elements().First(e => e.Name.LocalName == "content");
var propertiesNode = contentNode.Elements().First(d => d.Name.LocalName == "properties" && d.Name.Namespace == namespaceM);
var accountIdNode = propertiesNode.Elements().First(d => d.Name.LocalName == "AccountId" && d.Name.Namespace == namespaceD);
var nameNode = propertiesNode.Elements().First(d => d.Name.LocalName == "Name" && d.Name.Namespace == namespaceD);
var accountIdText = accountIdNode.Value;
var nameText = nameNode.Value;
}
}