Click here to Skip to main content
15,895,256 members
Please Sign up or sign in to vote.
2.00/5 (1 vote)
See more:
I have this file Downloaded

File starts here..

XML
<?xml version="1.0" encoding="ISO-8859-1" ?>
- <HostipLookupResultSet version="1.0.1" xmlns:gml="http://www.opengis.net/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.hostip.info/api/hostip-1.0.1.xsd">
  <gml:description>This is the Hostip Lookup Service</gml:description>
  <gml:name>hostip</gml:name>
- <gml:boundedBy>
  <gml:Null>inapplicable</gml:Null>
  </gml:boundedBy>
- <gml:featureMember>
- <Hostip>
  <ip>107.6.97.20</ip>
  <gml:name>(Unknown City?)</gml:name>
  <countryName>(Unknown Country?)</countryName>
  <countryAbbrev>XX</countryAbbrev>
- <!--  Co-ordinates are unavailable
  -->
  </Hostip>
  </gml:featureMember>
  </HostipLookupResultSet>


File Ends here...

I Capture it with this code

VB
Using client = New WebClient()
Dim strFile = client.DownloadString(String.Format("http://api.hostip.info/?ip=" + IpAddress))



All I need if the data here..

XML
<ip>107.6.97.20</ip>
<gml:name>(Unknown City?)</gml:name>
<countryName>(Unknown Country?)</countryName>
<countryAbbrev>XX</countryAbbrev>


I have no idea how to capture the City, Country and Code and populate a text field.

If someone could provide me a simple example of how to do this, I would be most grateful.

Thanks,

-Ron
Posted

It looks like XML. :-)

You can use any of the XML parsers offered by .NET FCL. This is my short review of them:
  1. Use System.Xml.XmlDocument class. It implements DOM interface; this way is the easiest and good enough if the size if the document is not too big.
    See http://msdn.microsoft.com/en-us/library/system.xml.xmldocument.aspx[^].
  2. Use the class System.Xml.XmlTextReader; this is the fastest way of reading, especially is you need to skip some data.
    See http://msdn.microsoft.com/en-us/library/system.xml.xmlreader.aspx[^].
  3. Use the class System.Xml.Linq.XDocument; this is the most adequate way similar to that of XmlDocument, supporting LINQ to XML Programming.
    See http://msdn.microsoft.com/en-us/library/system.xml.xmldocument.aspx[^], http://msdn.microsoft.com/en-us/library/bb387063.aspx[^].


[EDIT: in response to follow-up questions]

With System.Xml.XmlDataDocument:
Top element: http://msdn.microsoft.com/en-us/library/system.xml.xmldocument%28v=vs.110%29.aspx[^],
to get any element's children:
http://msdn.microsoft.com/en-us/library/system.xml.xmlnode.childnodes%28v=vs.110%29.aspx[^],
http://msdn.microsoft.com/en-us/library/system.xml.xmlnodelist%28v=vs.110%29.aspx[^],
to get child: http://msdn.microsoft.com/en-us/library/system.xml.xmlnodelist.item%28v=vs.110%29.aspx[^].

—SA
 
Share this answer
 
v2
Comments
Member 10315514 6-Jan-15 8:05am    
Hi,

Yes, I was able to locate those articles before I posted here. Thank you for the time you took to answer me. I do appreciate someone willing to help.

I have tried many ways to read the data and work my way through it with no success. I'm really just not getting XML.

Here is my latest..

Dim strFile = client.DownloadString(String.Format("http://api.hostip.info/?ip=" + IpAddress))
Dim m_xmld As XmlDocument
Dim m_nodelist As XmlNodeList
Dim m_node As XmlNode

m_xmld = New XmlDocument()
m_xmld.Load(strFile)

m_nodelist = m_xmld.SelectNodes("/Hostip")

For Each m_node In m_nodelist
'Get the City Name
HoldData.City = m_node.Attributes.GetNamedItem("gml:name").Value
'Get the Country
HoldData.CountryName = m_node.Attributes.GetNamedItem("countryName").Value
'Get the Country code
HoldData.CountryCode = m_node.Attributes.GetNamedItem("countryAbbrev").Value
Next


This code fails on the load and I never get further.

If you could, would you provide the code to read the data and parse through it? I know it seems like I'm asking for you to do my work for me, but it really is a much easier teaching tool to have a working solution to learn from than to fumble through on my own mistakes.

Thanks,

-Ron
Sergey Alexandrovich Kryukov 6-Jan-15 10:41am    
Well, use the debugger. What does it mean, "fails"? In what line? What exception?
—SA
Member 10315514 6-Jan-15 10:54am    
Hi Sergey,

Here is all I get from the Debugger...


Illegal characters in path.

System.ArgumentException was caught:{Cannot evaluate expression because we are stopped in native code.}

-Ron
Member 10315514 6-Jan-15 11:14am    
Ok. I changed the .Load to .LoadXML and I was able to load the file. But the rest of the code was no good.

My For Each loop failed on the first try with zero results returned. I am obviously doing something wrong. I just don't know what?

-Ron
Sergey Alexandrovich Kryukov 6-Jan-15 11:53am    
I would never use the actual strings in search. I would rather traverse the DOM to a certain level. Most likely, the location of the nodes you are interested in is fixed. For example, the algorithm could be like this:
1) go to the first child level of the document;
2) take last child; this takes you to the element "gml:featureMember";
3) take the only (or the first) child of it; the element "Hostip";
4) take children of these element one by one;
5) for each, take their text nodes.

That's all.

You are using hard-coded immediate constants of string type; it will be hard to maintain, easier to make a mistake which cannot be detected by a compiler.

Use the debugger.

—SA
It is simple as that:
VB
Dim IpAddress as String = ""
Dim client as New WebClient()
Dim strFile as string = client.DownloadString(String.Format("http://api.hostip.info/?ip={0}",IpAddress))

Dim xml as XDocument = XDocument.Parse(strFile)
Dim xnm as New XmlNamespaceManager(new NameTable())
xnm.AddNamespace("gml", "http://www.opengis.net/gml")
Console.WriteLine(xml.XPathSelectElement("//ip", xnm).Value)
Console.WriteLine(xml.XPathSelectElement("//Hostip/gml:name", xnm).Value)
Console.WriteLine(xml.XPathSelectElement("//countryName", xnm).Value)
Console.WriteLine(xml.XPathSelectElement("//countryAbbrev", xnm).Value)
 
Share this answer
 
v3
Comments
Member 10315514 6-Jan-15 14:51pm    
Hi,

Thank you for the code it worked with one exception, the value of Console.WriteLine(xml.XPathSelectElement("//gml:name", xnm).Value) was "Hostip" not the City name. It seems that the code above took the first occurrence of gml:name, not the second. How would I acquire the data from the second occurrence?

Also, I do not understand these two lines...

Dim xnm as New XmlNamespaceManager(new NameTable())
xnm.AddNamespace("gml", "http://www.opengis.net/gml")

Like I said. I really do not know anything about XML or how to manipulate the data.

Thanks for your time and patience.

-Ron
Zoltán Zörgő 6-Jan-15 15:10pm    
Use Console.WriteLine(xml.XPathSelectElement("//Hostip/gml:name", xnm).Value) instead

Remove those two code rows and you will see :) As the file is using namespaces, you need to address this. If you don't know, learn. You could read this article about namespaces: http://www.sitepoint.com/xml-namespaces-explained/. For the rest, you should read the articles linked by Sergey.
Member 10315514 6-Jan-15 15:23pm    
That did it. Thank you very much. I really do appreciate it. Just so I understand. Searching for a particular element within a group, I would use the tree level path like you did using the "//". So say for instance the data I required were down one more branch, I would search by the exact tree structure to get to the data like so...
"//Hostip/gml:name/City:name"
-Hopstip
--gml:name
---City(Data)

Correct?

I'll read the namespace article now.

-Ron
Zoltán Zörgő 6-Jan-15 15:33pm    
It is not that simple. I was using XPath notation to execute an XQuery to get specific element(s) from XML. Please take a look here: http://msdn.microsoft.com/en-us/library/ms256086%28v=vs.110%29.aspx
Member 10315514 6-Jan-15 15:54pm    
Thank you for your time. You've been great. XML is not a simple thing to learn. I'll keep plugging away at it though. The code you wrote worked fantastic. I am already using it for other purposes. I'm grateful the data I'm working with is all relatively the same and to you for helping me out.

Thanks Again,

-Ron

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900