我正在从这个天气链接“http://alerts.weather.gov/cap/us.php?x=0”解析此XML。我找到了一个很好的示例代码,它非常适合解析'tile'和'cap:event',除了我需要解析'cap:geocode'并得到一个('value'&''valueName')元素列表
<entry>
...
<cap:geocode>
<valueName>FIPS6</valueName>
<value>002016</value>
<valueName>UGC</valueName>
<value>AKZ185</value>
</cap:geocode>
...
</entry>
以下是我正在使用的代码:
XDocument doc = XDocument.Parse(objText);
XNamespace ns = XNamespace.Get("http://www.w3.org/2005/Atom");
XNamespace nsCap = XNamespace.Get("urn:oasis:names:tc:emergency:cap:1.1");
var xlist = doc.Descendants(ns + "entry").Select(elem => new
{
Title = elem.Descendants(ns + "title").FirstOrDefault(),
AreaDesc = elem.Descendants(nsCap + "areaDesc").FirstOrDefault(),
Geocode = elem.Descendants(nsCap + "geocode").Select( gc => new
{
val = gc.Element("value"),
valName = gc.Element("valueName")
}).ToList()
});
foreach (var el in xlist)
{
System.Diagnostics.Debug.WriteLine(string.Format("title: {0}, AreaDesc: {1}",
el.Title != null ? el.Title.Value : string.Empty,
el.AreaDesc != null ? el.AreaDesc.Value : string.Empty));
foreach (var x in el.Geocode)
{
string value = x.val.Value;
string valueName = x.valName.Value;
}
}
当我运行代码时,el.Geocode元素包含null。我不确定为什么它不给我价值。
这是来自weather.gov的XML:
<?xml version = '1.0' encoding = 'UTF-8' standalone = 'yes'?>
<!--
This atom/xml feed is an index to active advisories, watches and warnings
issued by the National Weather Service. This index file is not the complete
Common Alerting Protocol (CAP) alert message. To obtain the complete CAP
alert, please follow the links for each entry in this index. Also note the
CAP message uses a style sheet to convey the information in a human readable
format. Please view the source of the CAP message to see the complete data
set. Not all information in the CAP message is contained in this index of
active alerts.
-->
<feed
xmlns = 'http://www.w3.org/2005/Atom'
xmlns:cap = 'urn:oasis:names:tc:emergency:cap:1.1'
xmlns:ha = 'http://www.alerting.net/namespace/index_1.0'
>
<!-- http-date = Thu, 13 Feb 2014 07:35:00 GMT -->
<id>http://alerts.weather.gov/cap/us.atom</id>
<logo>http://alerts.weather.gov/images/xml_logo.gif</logo>
<generator>NWS CAP Server</generator>
<updated>2014-02-13T14:35:00-05:00</updated>
<author>
<name>w-nws.webmaster@noaa.gov</name>
</author>
<title>Current Watches, Warnings and Advisories for the United States Issued by the National Weather Service</title>
<link href='http://alerts.weather.gov/cap/us.atom'/>
<entry>
<id>http://alerts.weather.gov/cap/wwacapget.php?x=AK12514240A72C.BlizzardWarning.1251424FD8A0AK.AFCWSWALU.51c52d9702226c0667b44fead05cc33e</id>
<updated>2014-02-13T09:43:00-09:00</updated>
<published>2014-02-13T09:43:00-09:00</published>
<author>
<name>w-nws.webmaster@noaa.gov</name>
</author>
<title>Blizzard Warning issued February 13 at 9:43AM AKST until February 14 at 9:00AM AKST by NWS</title>
<link href='http://alerts.weather.gov/cap/wwacapget.php?x=AK12514240A72C.BlizzardWarning.1251424FD8A0AK.AFCWSWALU.51c52d9702226c0667b44fead05cc33e'/>
<summary>...ARCTIC AIR RETURNING TO SOUTHWEST ALASKA... .VERY COLD AIR ACCOMPANIED BY BRISK NORTHERLY WINDS WILL MAKE FOR DANGEROUS WIND CHILLS ACROSS MUCH OF SOUTHWEST ALASKA THROUGH FRIDAY. THESE WIND CHILL VALUES WILL BE SOME OF THE COLDEST OF THE ENTIRE WINTER THUS FAR. STRENGTHENING WINDS WILL CONTINUE TO SURGE SOUTHWARD ALONG THE ALASKA PENINSULA AND EASTERN ALEUTIANS.</summary>
<cap:event>Blizzard Warning</cap:event>
<cap:effective>2014-02-13T09:43:00-09:00</cap:effective>
<cap:expires>2014-02-14T09:00:00-09:00</cap:expires>
<cap:status>Actual</cap:status>
<cap:msgType>Alert</cap:msgType>
<cap:category>Met</cap:category>
<cap:urgency>Expected</cap:urgency>
<cap:severity>Severe</cap:severity>
<cap:certainty>Likely</cap:certainty>
<cap:areaDesc>Eastern Aleutians</cap:areaDesc>
<cap:polygon></cap:polygon>
<cap:geocode>
<valueName>FIPS6</valueName>
<value>002016</value>
<valueName>UGC</valueName>
<value>AKZ185</value>
</cap:geocode>
<cap:parameter>
<valueName>VTEC</valueName>
<value>/X.UPG.PAFC.WW.Y.0009.140213T2300Z-140214T1800Z/
/X.EXB.PAFC.BZ.W.0007.140213T1843Z-140214T1800Z/</value>
</cap:parameter>
</entry>
<entry>
<id>http://alerts.weather.gov/cap/wwacapget.php?x=AK12514240A72C.BlizzardWarning.125142504DD0AK.AFCWSWALU.b6bd8b4269647f8f24176412e2248b93</id>
<updated>2014-02-13T09:43:00-09:00</updated>
<published>2014-02-13T09:43:00-09:00</published>
<author>
<name>w-nws.webmaster@noaa.gov</name>
</author>
<title>Blizzard Warning issued February 13 at 9:43AM AKST until February 14 at 12:00PM AKST by NWS</title>
<link href='http://alerts.weather.gov/cap/wwacapget.php?x=AK12514240A72C.BlizzardWarning.125142504DD0AK.AFCWSWALU.b6bd8b4269647f8f24176412e2248b93'/>
<summary>...ARCTIC AIR RETURNING TO SOUTHWEST ALASKA... .VERY COLD AIR ACCOMPANIED BY BRISK NORTHERLY WINDS WILL MAKE FOR DANGEROUS WIND CHILLS ACROSS MUCH OF SOUTHWEST ALASKA THROUGH FRIDAY. THESE WIND CHILL VALUES WILL BE SOME OF THE COLDEST OF THE ENTIRE WINTER THUS FAR. STRENGTHENING WINDS WILL CONTINUE TO SURGE SOUTHWARD ALONG THE ALASKA PENINSULA AND EASTERN ALEUTIANS.</summary>
<cap:event>Blizzard Warning</cap:event>
<cap:effective>2014-02-13T09:43:00-09:00</cap:effective>
<cap:expires>2014-02-14T12:00:00-09:00</cap:expires>
<cap:status>Actual</cap:status>
<cap:msgType>Alert</cap:msgType>
<cap:category>Met</cap:category>
<cap:urgency>Expected</cap:urgency>
<cap:severity>Severe</cap:severity>
<cap:certainty>Likely</cap:certainty>
<cap:areaDesc>Alaska Peninsula</cap:areaDesc>
<cap:polygon></cap:polygon>
<cap:geocode>
<valueName>FIPS6</valueName>
<value>002013 002164</value>
<valueName>UGC</valueName>
<value>AKZ181</value>
</cap:geocode>
<cap:parameter>
<valueName>VTEC</valueName>
<value>/X.EXT.PAFC.BZ.W.0007.140213T1843Z-140214T2100Z/</value>
</cap:parameter>
</entry>
</entry>
</feed>
答案 0 :(得分:2)
我认为您的第一个问题是您在代码的这一部分缺少命名空间
val = gc.Element("value"),
valName = gc.Element("valueName")
我认为您的第二个问题是您已将匿名类型的GeoCode属性编写为<cap:geocode>
元素的列表,而您希望将其用作valueName / value对的列表<cap:geocode>
元素。至少这是我的假设。因此,这可能更接近你想要的
var xlist = doc.Descendants(ns + "entry").Select(elem => new
{
Title = elem.Descendants(ns + "title").FirstOrDefault(),
AreaDesc = elem.Descendants(nsCap + "areaDesc").FirstOrDefault(),
GeocodeElements = elem.Descendants(nsCap + "geocode").Descendants()
});
foreach (var el in xlist)
{
System.Diagnostics.Debug.WriteLine(string.Format("title: {0}, AreaDesc: {1}",
el.Title != null ? el.Title.Value : string.Empty,
el.AreaDesc != null ? el.AreaDesc.Value : string.Empty));
var geoCodeValues = el.GeocodeElements
.Where(o => o.Name == ns + "value").ToList();
var geoCodeValueNames = el.GeocodeElements
.Where(o => o.Name == ns + "valueName").ToList();
var pairs = geoCodeValueNames.Zip(geoCodeValues, (vn, v) =>
new Tuple<String, String>(vn.Value, v.Value)).ToList();
}
请注意,在最后一行中我使用了Tuples而不是匿名类型,因为它不会让我创建一个具有两个名为“Value”的属性的匿名类型。我希望这只是一个开始(我不确定我的代码有多强大 - 如果不是每个值都与valueName配对等等),并且可能有其他方法来解决这个问题。我只是想让你更接近我认为你想做的事情。