Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

How To Read NOAA XML "weather-summary" Attribute?

Participant ,
Jun 01, 2015 Jun 01, 2015

Can someone help with Flash CS6 ActionScript 3 E4X syntax for reading National Weather Service’s XML feed (National Weather Service)? 

I’ve been able to address most of the needed fields; but, XML attribute "weather-summary" is driving me to drink!  Looping, I can locate it, but results always come back blank.  Any help is appreciated.  I’ve tried a number of approaches including:

for each(var elemParamters:XML in rssXML.data.(@type == "current observations").elements("parameters")) {
       :

       :

     

for each (var elemWeather:XML in elemParamters.weather.elements("weather-conditions") ) {
       if ( elemWeather.hasOwnProperty("@weather-summary") ) {
        currentConditions = elemWeather.("@weather-summary");
        currentConditions = elemWeather.("@weather-summary[0]");
        trace("\n elemWeather = {" + elemWeather +"}");
        }
       }
      trace("\n currentConditions? = {" + currentConditions +"}");

       :

       :

Sample XML:

<dwml>
<data>
:
:
:
</data>
<data type="current observations">
<location>
  <location-key>point1</location-key>
  <point latitude="39.11" longitude="-84.42"/>
  <area-description>Cincinnati, Cincinnati Municipal Airport Lunken Field, OH</area-description>
  <height datum="mean sea level" height-units="feet">482</height>
</location>
<moreWeatherInformation applicable-location="point1">http://www.nws.noaa.gov/data/obhistory/KLUK.html</moreWeatherInformation>
<time-layout time-coordinate="local">
  <layout-key>k-p1h-n1-1</layout-key>
  <start-valid-time period-name="current">2015-04-29T13:53:00-04:00</start-valid-time>
</time-layout>
<parameters applicable-location="point1">
  <temperature type="apparent" units="Fahrenheit" time-layout="k-p1h-n1-1">
   <value>65</value>
  </temperature>
  <temperature type="dew point" units="Fahrenheit" time-layout="k-p1h-n1-1">
   <value>43</value>
  </temperature>
  <humidity type="relative" time-layout="k-p1h-n1-1">
   <value>45</value>
  </humidity>
  <weather time-layout="k-p1h-n1-1">
   <name>Weather Type, Coverage, Intensity</name>
   <weather-conditions weather-summary="Partly Cloudy"/>
   <weather-conditions>
    <value>
     <visibility units="statute miles">10.00</visibility>
    </value>
   </weather-conditions>
  </weather>
  <conditions-icon type="forecast-NWS" time-layout="k-p1h-n1-1">
   <name>Conditions Icon</name>
   <icon-link>http://forecast.weather.govnewimages/medium/sct.png</icon-link>
  </conditions-icon>
  <direction type="wind" units="degrees true" time-layout="k-p1h-n1-1">
   <value>999</value>
  </direction>
  <wind-speed type="gust" units="knots" time-layout="k-p1h-n1-1">
   <value>15</value>
  </wind-speed>
  <wind-speed type="sustained" units="knots" time-layout="k-p1h-n1-1">
   <value>5</value>
  </wind-speed>
  <pressure type="barometer" units="inches of mercury" time-layout="k-p1h-n1-1">
   <value>29.84</value>
  </pressure>
</parameters>
</data>
</dwml>

TOPICS
ActionScript
1.6K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Participant , Jun 04, 2015 Jun 04, 2015

Technique for loop for(var i:int=0;i<outputxml..weather.length();i++){ could be something like:

var iCondition:Number = -1;
for(var i:int=0; i<rssXML...weather.length(); i++){
    ++ iCondition;
    if ( iCondition == 1 ) { currentConditions = rssXML..weather['weather-conditions'].@['weather-summary']; };
  };

Solution for question as originally asked turns out to be method toXMLString().  XML data structure was filtered down to working with only the qualified XML region.  Here's the AS3 E4X code:


  

...
Translate
Community Expert ,
Jun 02, 2015 Jun 02, 2015

use bracket notation to access hyphenated nodes/attributes.  eg, if you assign sampleXML to samplexml = XML(e.target.data) in your complete listener:

for(var i:int=0;i<samplexml..weather.length();i++){

samplexml..weather['weather-conditions'].@['weather-summary']);

}

(p.s when using the adobe forums, please mark helpful/correct responses, if there are any.)

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jun 02, 2015 Jun 02, 2015

For me, it’s not that simple.  I does not work.

I previously tried unsuccessfully using brackets.  It still returns an empty result (instead of ”Partly Cloudy”).  Weather XML element/attribute names are a hodge/podge mix of program language reserved words/mathematical operators.  It makes stepping through XML structure a land mine. 

 

Encapsulating “for each” loop had targeted down to just the “weather-condition” elements.  The 1st weather-conditions element (of 2) is (currently) the only one containing attribute “weather-summary” and it has no element value.  That’s why loop first matches hasOwnProperty("@weather-summary").  Loop works. It just doesn’t pass the attribute value:

      for each (var elemWeather:XML in elemParamters.weather.elements("weather-conditions") ) {
        if ( elemWeather.hasOwnProperty("@weather-summary") ) {
          trace("\n elemWeather = {" + elemWeather +"}");
         }
       }
       trace("\n currentConditions? = {" + currentConditions +"}"); 

// trace output: currentConditions? = {}

I tried your index method, but it also fails. Using only square brackets returns zero XML collection length.  Elements() and atrubute() finds data.  But with work arounds for XMLs funky mix of name/attribute , index syntax (on element “weather-condition”) does not “fit”.

   var lenCond:int = -1;

     var currentConditions2:String;

     lenCond = elemParamters.weather.elements("weather-conditions").length();

     trace("\n elemParamters.weather.['weather-conditions'].length() = {" + lenCond +"}");

/ trace output: elemParamters.weather.['weather-conditions'].length() = {2}

     for (var i:int=0; i<lenCond; i++){

           // fails:

           currentConditions2 = elemParamters.weather.element("weather-conditions").attribute("weather-summary");

           trace("\n currentConditions2? = {" + currentConditions2 +"}");

     }   

I'm hoping for any working syntax... 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jun 02, 2015 Jun 02, 2015

it works.

show your load method and load complete listener.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jun 02, 2015 Jun 02, 2015

Flash loader design is based on "Adobe Flash Professional CS5 and Flex 4 samples" (http://www.adobe.com/devnet/flash/samples.html).  From page's zip file FlashPlatformAS3DevGuideExamples.zip (ZIP, 25 MB),  example RSSViewer aplication: \FlashPlatformAS3DevGuideExamples.zip\FlashPlatformExamples\RSSViewer\.  ActionScript is RSSParser.as.

Duplicated code RSSParser to NOAAParser, repointed NOAAParser code to an example (local copy) weather XML file, and began adapting its XML traversal coding (no weather specific display output).

I'd gladly attach a copy of sample RSSParser.as, but do not see a forum file attachment method.  Starting content is:

    package com.example.programmingas3.rssViewer {
       import flash.net.URLRequest;
       import flash.net.URLLoader;
       import flash.events.*;

       /**

        * RSSParser includes methods for

        * converting RSS XML data into HTML text.

        */

     public class RSSParser extends EventDispatcher {

     :

     :

What is needed to load complete listener? What does it provide?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jun 02, 2015 Jun 02, 2015

ok, then what are the first lines of elemWeather showing at least enough to display a complete first child node?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jun 02, 2015 Jun 02, 2015

It seems pretty straightforward:

  public function xmlLoaded(evtObj:Event):void {
   rssXML = XML(myLoader.data);
   /* trace("trace(rssXML)= [" + rssXML + "]."); */
   var outXML:XMLList = new XMLList();
      :
      :

   for each(var elemParamters:XML in rssXML.data.(@type == "current observations").elements("parameters")) {
       trace ("\n elemParamters " + elemParamters.localName());

          :

          :

       for each (var elemWeather:XML in elemParamters.weather.elements("weather-conditions") ) {
           if ( elemWeather.hasOwnProperty("@weather-summary") ) {
               currentConditions = elemWeather.("@weather-summary");
               //currentConditions = elemWeather.property("weather-summary");
               currentConditions = elemWeather.("@weather-summary[0]");              

               }

           }

      :

      :

   }

Code is recognizing and acting upon the hasOwnProperty("@weather-summary") if test.  It's just not passing its attribute value to variable currentConditions.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jun 02, 2015 Jun 02, 2015

use:

for(var i:int=0;i<outputxml..weather.length();i++){

trace(outputxml..weather['weather-conditions'].@['weather-summary']);

}

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jun 02, 2015 Jun 02, 2015

p.s. that's not an upper case 'el' at the end of outputxm.  that's an 'el' 'dot' 'dot'

p.p.s. i enlarged the font to make it easier to read, not to be obnoxious.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jun 02, 2015 Jun 02, 2015

You've been trying to help me to the solution.  Object "outputxml" equates to my "rssXML" and it works!

public function xmlLoaded(evtObj:Event):void {
  rssXML = XML(myLoader.data);
       :
       :
trace("\n\n rssXML..weather.length() = " + rssXML..weather.length());
// trace output:  rssXML..weather.length() = 2
for (var i:int=0; i<rssXML..weather.length(); i++) {
      trace("\n rssXML..weather[" +i +"]...= " + rssXML..weather['weather-conditions'].@['weather-summary']);
     }
// trace output: rssXML..weather[0]...= Mostly SunnyMostly Cloudy then Chance ShowersShowers LikelyMostly CloudyPartly SunnyPartly CloudyMostly SunnyPartly CloudyPartly SunnyMostly CloudyPartly SunnyChance T-stormsChance T-storms
// trace output: rssXML..weather[1]...= Partly Cloudy

"weather[0]" is an earlier region of the XML. It contains multiple days forecast. "weather[1]" is the value needed!  I'll add in the need parent qualification tomorrow and provide a better response.

Thanks

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jun 02, 2015 Jun 02, 2015

you're welcome.

p.s when using the adobe forums, please mark helpful/correct responses, if there are any.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jun 04, 2015 Jun 04, 2015
LATEST

Technique for loop for(var i:int=0;i<outputxml..weather.length();i++){ could be something like:

var iCondition:Number = -1;
for(var i:int=0; i<rssXML...weather.length(); i++){
    ++ iCondition;
    if ( iCondition == 1 ) { currentConditions = rssXML..weather['weather-conditions'].@['weather-summary']; };
  };

Solution for question as originally asked turns out to be method toXMLString().  XML data structure was filtered down to working with only the qualified XML region.  Here's the AS3 E4X code:


     for each(var elemParamters:XML in rssXML.data.(@type == "current observations").elements("parameters")) {
      for each (var elemWeather:XML in elemParamters.weather.elements("weather-conditions") ) {
       if ( elemWeather.hasOwnProperty("@weather-summary") ) {
                 currentConditions = elemWeather.attribute("weather-summary").toXMLString();

trace("\n currentConditions? = {" + currentConditions +"}");

// trace output:     currentConditions? = {Partly Cloudy}

}

       }

It's not clear why to get needed results XML method toString() is wrong and toXMLString() is correct, when objective is to extract XML to a string?

kglad; Thanks again for working with me on my question. 

Guy McMickle

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines