在c#中使用linq to XML从返回null的XML中访问后代元素
本文关键字:XML null 访问 后代 元素 返回 linq to | 更新日期: 2023-09-27 18:06:12
请人们帮助我,我需要消费一个从我的应用程序返回xml的web服务,下载xml的代码工作正常,但我需要从xml文件中提取值,但我不断从代码中获得null返回值,精确地GetLocationFromXml()方法是返回null的方法,GetLocationAsXMLFromHost()方法工作正常。
这是完整的类
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";
private 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;
}
}
和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>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>
考虑到这些注释,我怀疑问题可能很简单:
private string _hostNameSpace = "hostip.info/api";
应:private string _hostNameSpace = "http://hostip.info/api";
(其他也一样)我个人会让XNamespace的值以:
开头private static readonly XNamespace HostNameSpace = "http://hostip.info/api";
编辑:好吧,在摆弄了你的例子之后(它本来可以更短更完整),我已经找出了问题所在:你正在寻找使用"主机名称空间"的元素-但是XML中的元素不在任何名称空间中。只要去掉那些命名空间位,它就可以正常工作了。