2014-02-13 3 views
1

Я работаю над разбором этого XML из этой погодной ссылки «http://alerts.weather.gov/cap/us.php?x=0». Я нашел хороший пример кода, и он отлично подходит для разбора «tile» и «cap: event», за исключением того, что мне нужно было проанализировать «cap: geocode» и получить список элементов («value» «valueName») под ним.Linq to XML, разбор с XNameSpace

<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 элементы содержат нуль. Я не уверен, почему это не дает мне ценности.

Вот XML из weather.gov:

 <?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>[email protected]</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>[email protected]</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>[email protected]</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> 

ответ

2

Я думаю, ваша первая проблема заключается в том, что вам не хватает пространства имен в этой части кода

val = gc.Element("value"), 
valName = gc.Element("valueName") 

Я думаю, что ваша вторая проблема заключается в том, что вы указали свойство GeoCode вашего анонимного типа как список элементов <cap:geocode>, в то время как вы ожидали использовать его как список пар value_name/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(); 
} 

Обратите внимание, что в этой последней строке я использовал кортежи вместо анонимных типов, потому что он не позволил бы мне создать анонимный тип, который имел два свойства, как назвал «Value» , Я ожидаю, что это только начало (я не уверен, насколько надежным является мой код), как, если не каждое значение сопряжено с именем valueN и т. Д.), И, вероятно, есть другие способы решения этой проблемы. Я просто пытался приблизиться к тому, что, как я думаю, вы пытаетесь сделать.