开发者

accessing descendant elements from an xml returned null using linq to xml in c#

开发者 https://www.devze.com 2023-03-29 12:54 出处:网络
Please people help me out I need to consume a web service that returns an xml from my application, The code that downloads xml works fine, but I need to extract values from the xml file, but I keep ge

Please people help me out I need to consume a web service that returns an xml from my application, The code that downloads xml works fine, but I need to extract values from the xml file, but I keep getting a null return value from the code, precisely the GetLocationFromXml() method is the method returning null, the GetLocationAsXMLFromHost() method works fine.

this is the complete class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AMIS.Core.DTOs;
using System.Net;
using System.Xml.Linq;
using System.Xml;
using System.Linq;

public class GeoLocationService
{
   private string _hostWebSite = "http://api.hostip.info";
    p开发者_如何学Gorivate readonly XNamespace _hostNameSpace = "http://www.hostip.info/api";
    private readonly XNamespace _hostGmlNameSpace = "http://www.opengis.net/gml";

public LocationInfo GetLocationInfoFromIPAddress(string userHostIpAddress)
{
    IPAddress ipAddress = null;
    IPAddress.TryParse(userHostIpAddress, out ipAddress);
    string xmlData = GetLocationAsXMLFromHost(ipAddress.ToString());
    LocationInfo locationInfo = GetLocationFromXml(xmlData);
    return locationInfo;
}

private string GetLocationAsXMLFromHost(string userHostIpAddress)
{
    WebClient webClient= new WebClient();
    string formattedUrl = string.Format(_hostWebSite + "/?ip={0}", userHostIpAddress);
    var xmlData = webClient.DownloadString(formattedUrl);
    return xmlData;
}

private LocationInfo GetLocationFromXml(string xmlData)
{
    LocationInfo locationInfo = new LocationInfo();
    var xmlResponse = XDocument.Parse(xmlData);
    var nameSpace = (XNamespace)_hostNameSpace;
    var gmlNameSpace = (XNamespace)_hostGmlNameSpace;

    try
    {
        locationInfo = (from x in xmlResponse.Descendants(nameSpace + "Hostip")
                        select new LocationInfo
                        {
                            CountryName = x.Element(nameSpace + "countryName").Value,
                            CountryAbbreviation = x.Element(nameSpace + "countryAbbrev").Value,
                            LocationInCountry = x.Element(gmlNameSpace + "name").Value
                        }).SingleOrDefault();
    }
    catch (Exception)
    {
        throw;
    }
    return locationInfo;
}
}

and the xml file is below

<?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>41.78.8.3</ip>
  <gml:name>(Unknown city)</gml:name>
  <countryName>NIGERIA</countryName>
  <countryAbbrev>NG</countryAbbrev>
  <!-- Co-ordinates are unavailable -->
  </Hostip>
</gml:featureMember>
</HostipLookupResultSet>


Given the comments, I suspect the problem may be as simple as:

private string _hostNameSpace = "hostip.info/api";

should be:

private string _hostNameSpace = "http://hostip.info/api";

(Ditto for the others.) Personally I'd make then XNamespace values to start with:

private static readonly XNamespace HostNameSpace = "http://hostip.info/api";

EDIT: Okay, after messing around with your example (which could have been a lot shorter and a lot more complete) I've worked out what's wrong: you're looking for elements using the "host namespace" - but the elements in the XML aren't in any namespace. Just get rid of those namespace bits, and it works fine.

0

精彩评论

暂无评论...
验证码 换一张
取 消