XML document - Object reference not set to an instance of an object - c#

I'm working on a website where I need a google map to display the positions of the members of the site.
However, i'm having a bit of trouble getting data from the returned XML document when using the HTTP Geocode Service. When I put the string into the browser it returns the XML just fine and if I set a textbox.Text to the documents InnerText it also displays as it should. But when I want to extract values from nodes, it says object reference not set to an instance of an object.
I'm doing it this way:
string address = m.getProperty("adresse").Value.ToString();
string zip = m.getProperty("postNummer").Value.ToString();
string city = m.getProperty("by").Value.ToString();
XmlDocument doc = new XmlDocument();
doc.Load("http://maps.googleapis.com/maps/api/geocode/xml?address=" + zip + "+" + city + "+" + address + "+DK&sensor=true");
XmlNode latNode = doc.SelectSingleNode("GeoCodeResponse/result/geometry/location/lat/text()");
XmlNode lonNode = doc.SelectSingleNode("GeoCodeResponse/result/geometry/location/lng/text()");
// The error occurs when the code hits these:
string lat = latNode.Value;
string lon = lonNode.Value;
I must admin that I haven't worked that much with XML in C# yet, so any hint will be greatly appreciated! :-) Should also say that the above code is in a foreach loop, looping through the members of the site.
Thanks a lot in advance!
All the best,
Bo
Edit: Sorry, I forgot to paste how I get the values! ;)

Replace "GeoCodeResponse" with "GeocodeResponse"
Please note the capital C in Code is incorrect. Xml is case sensitive.

How did you get latNode and lonNode ? It seems to be those that are null.
Since you are doing it in a loop, does any of the members succeed ? Perhaps you are not getting a hit for some of the addresses, so the lat/long nodes in the document might not be there ?
There really is no way to tell the exact problem from the code you posted. Use your debugger, and step through the code to see why you are not getting latNode assigned.
Edit
This works:
XmlNode latNode = doc.SelectSingleNode("GeocodeResponse/result/geometry/location/lat/text()");
XmlNode lonNode = doc.SelectSingleNode("GeocodeResponse/result/geometry/location/lng/text()");
You had a little type in the path. "code" in "GeocodeResponse" should be lowercase. XPath is case sensitive.

Related

how to get innertext from xmlnode C#

after I deserialized the xml, i'm able to parse all the elements and attributes. One of the attributes return an XmlNode. When expand the node, I could see the inner text, but not sure how to extract it. Any suggestion?
Since you don't have a code example
XmlNode xnode;
string name = xnode.InnerText;
or on you example
string date = attribute.DateValue[0].InnerText;
You want to get everything from it? I mean everything, that is under the "[0]" in debugger?
Usually You just have to get the value from InnerText - same as if You want to put something into the node, You assign it to InnerText field.
I've got it figure out..
var xn = (XmlNode[])attribute.DateValue;
var sdate = xn[0].InnerText;
Thanks guys!

Html Agility Pack, search through site for a specified string of words

I'm using the Html Agility Pack for this task, basically I've got a URL, and my program should read through the content of the html page on it, and if it finds a line of text (ie: "John had three apples"), it should change a label's text to "Found it".
I tried to do it with contains, but I guess it only checks for one word.
var nodeBFT = doc.DocumentNode.SelectNodes("//*[contains(text(), 'John had three apples')]");
if (nodeBFT != null && nodeBFT.Count != 0)
myLabel.Text = "Found it";
EDIT: Rest of my code, now with ako's attempt:
if (CheckIfValidUrl(v)) // foreach var v in a list..., checks if the URL works
{
HtmlWeb hw = new HtmlWeb();
HtmlDocument doc = hw.Load(v);
try
{
if (doc.DocumentNode.InnerHtml.ToString().Contains("string of words"))
{
mylabel.Text = v;
}
...
One possible option is using . instead of text(). Passing text() to contains() function the way you did will, as you suspected, effective only when the searched text is the first direct child of the current element :
doc.DocumentNode.SelectNodes("//*[contains(., 'John had three apples')]");
In the other side, contains(., '...') evaluates the entire text content of current element, concatenated. So, just a heads up, the above XPath will also consider the following element for example, as a match :
<span>John had <br/>three <strong>apples</strong></span>
If you need the XPath to only consider cases when the entire keyword contained in a single text node, and therefore considers the above case as a no-match, you can try this way :
doc.DocumentNode.SelectNodes("//*[text()[contains(., 'John had three apples')]]");
If none of the above works for you, please post minimal HTML snippet that contains the keyword but returned no match, so we can examine further what possibly causes that behavior and how to fix it.
use this:
if (doc.DocumentNode.InnerHtml.ToString().Contains("John had three apples"))
myLabel.Text="Found it";

Programmatically get amount of facebook likes for a specific page

I'm building a website in ASP.net/C# and currently I want to get the amount of Facebook likes of a specific page (think of a video/article). I need this value programmatically, because I want to sort on it later, but that's a different story.
I already know the link Facebook itself provides to get this amount, which is posted below.
http://api.facebook.com/method/fql.query?query=select%20like_count%20from%20link_stat%20where%20url=%27http://www.google.com%27
With www.google.com being the website, whose links are being counted and can of course be changed to whichever page one needs.
Does anybody know how I can access the xml file, of the URL/XML file posted above? I've done some research, but I can't seem to find an answer that works for me.
EDIT: I found the answer. I had to navigate through the XML a bit and modify the actual URL used. Working code is posted below.
string result;
string urlToXMLfile, currentURL;
currentURL = Globals.NavigateURL(TabId, "", "CategoryId=" + catId, "MovieId=" + Request.QueryString["MovieId"]);
urlToXMLfile = "https://api.facebook.com/method/fql.query?query=select%20%20like_count%20from%20link_stat%20where%20url=%22";
urlToXMLfile += currentURL;
urlToXMLfile += "%22";
//XDocument xdoc = XDocument.Load(urlToXMLfile);
//string test = xdoc.Descendants(XName.Get("like_count")).First().Value;
XmlDocument doc = new XmlDocument();
doc.Load(urlToXMLfile);
result = doc.FirstChild.NextSibling.InnerText;
return result;
I had same issue once, when I've worked with Selenium. I found that for me it was ok just to get the text representation of that xml and keep it simple string, storing the HTML body in a variable. Which allowed me later to extract the count I need via regex or other algorithm.
I added my own answer below the question. That line of code works and returns a simple String, with the amount of FB likes that page got.
I found a Selenium solution for you, try this:
string pageSource = driver.getPageSource();
and after you get the data, you can do something like:
// Extract the text between the two like_count elements
pattern = "(?i)(<like_count.*?>)(.+?)(</like_count>)";

Adding xml namespaces to code programatically

I am working on some code in C# where I want the output as the text present at some xpath from some xml-file. Now as the xml file keeps changing and so do the namespaces, I don't want to hardcode the namespaces in the code.
XmlDocument xml = new XmlDocument();
xml.Load(file);
XmlNamespaceManager nsMgr = new XmlNamespaceManager(xml.NameTable);
Now as the namespace keeps changing I am thinking of reading the xml and using some string operations to get the namspace and uri string:
string s = System.IO.File.ReadAllText(file);
string[] s1 = new string[1];
s1[0]="xmlns:";
string[] s3 = s.Split(s1, System.StringSplitOptions.None);
foreach (string k in s3)
{
nsMgr.AddNamespace( k.Substring( 0 , k.IndexOf('=') - 1) , need help for this )
}
Some sample values of k after the split operation are:
"xs=\"http://www.w3.org/2001/XMLSchema\" "
"location=\"urn:x-ABC:content:location:mastering:1\" "
"entity=\"urn:x-ABC:content:identified-entities:mastering:1\" "
I need help on second parameter of nsMgr.AddNamespace(). Also if there is a cleaner way of adding namespaces without hardcoding.
EDIT:- Clarifying what i am doing here. I am trying to write a winform through which onc can get output as text present at some xpath in some xml. So winform takes 2 inputs .One is xml file location and other is xpath . The output should be the text at that xpath location.
For example
<a>
<b>abc
</b>
</a>
if user searches for //b or a/b then output should be abc.
The code works fine when there are default namespaces , but when the xml has namespaces defined i need to include them in the code. As i want to make the code generic , so i cannot hardcode the namespaces.

Checking if element exists in XML file

I need to check if an element in XML file exists. After searching here, I have tried a code from one of very similiar questions I found here, so the code looks like this(it is looped using foreach so it checks every airport in group airports):
string icao = airport.Attributes.GetNamedItem("icao").Value;
if(airports.SelectSingleNode("/vEsup/airports/airport/" + icao + "/departures")==null)
{
MessageBox.Show("I exist!");
}
Please note that the message box is just for testing, I find it the easiest way to check if the code is working properly. However, I found out that whatever path I enter, it always shows the messagebox, regardless if it exist in the XML file or not.
You can use Linq to query specific xml nodes and attributes also.
Here is link to similar sample:
http://www.codearsenal.net/2012/07/c-sharp-load-xml-using-xlinq.html
"shows the messagebox if it exist in the XML file or not." seems to be incorrect as you checking for node not to be present in XML if (a.SelectSingleNode(...)==null).
Most likely you need to correctly specify namespaces to you nodes. (need sample XML to give any better suggestion)
In your 'if' block, aren't you checking to see IF the string is null?
My guess - and I could be wrong here - is that you meant:
string icao = airport.Attributes.GetNamedItem("icao").Value;
if(airports.SelectSingleNode("/vEsup/airports/airport/" + icao + "/departures")!=null)
{
return true;
}
MessageBox.Show("I exist!");

Categories

Resources