3 # TODO handle xsi:nil="true" handling
4 # TODO can soap data be received as stream, so we don't have to store giant string?
5 # TODO cache SOAP response with all data, and only update that occasionally, to
6 # prevent hammering the NWS servers, also, to speed up the scripts.
7 # TODO is visibility handling right? Have never seen it not nil, so I don't know
8 # what its going to look like. Update: I think nil means unlimited from looking
9 # at table 7 in http://www.weather.gov/mdl/XML/Design/MDL_XML_Design.htm, still
10 # waiting to get something other than nil though.
15 use base
qw(XML::SAX::Base);
29 ########### Parsing Methods ##################
34 if (
$name eq
'time-layout') {
35 $expat->setHandlers( Start => \&timeStart, Char => \&timeChar );
39 if (
$name eq
'parameters') {
40 $expat->setHandlers( Start => \&weatherStart, End => \&weatherEnd, Char => \&weatherChar );
46 if (
$name eq
'time-layout') {
48 $expat->{CurrDay} = 0;
49 $expat->{CurrNight} = 0;
50 undef $expat->{TimeDate};
51 $expat->setHandlers( Char => \&Text, Start => \&StartTag );
59 if ($expat->in_element(
'creation-date')) {
72 if (
$name eq
'value') {
75 foreach $attr (keys(%atts)) {
78 push @{$weatherdata{$timestr}->{$currLbl}}, $condhash;
81 if (
$name eq
'visibility') {
83 $index = $#{$weatherdata{$timestr}->{$currLbl}};
84 if ($atts{
'xsi:nil'}) {
85 $weatherdata{$timestr}->{$currLbl}->[
$index]->{visibility} =
92 my ($expat, $text) = @
_;
93 if ($expat->in_element(
'visibility')) {
95 $weatherdata{$timestr}->{$currLbl}->{visibility} = $text;
102 if (
$name eq
'weather') {
103 $expat->setHandlers( Start => \&weatherStart,
104 End => \&weatherEnd, Char => \&weatherChar );
106 if (
$name eq
'weather-conditions') {
107 $expat->{timeindex}++;
114 if ($expat->in_element(
'parameters')) {
117 $currLbl .=
"_$atts{type}";
120 $expat->{timeindex} = 0;
122 if (
$name eq
'weather') {
123 $expat->setHandlers( Start => \&conditionsStart,
124 End =>\&conditionsEnd, Char => \&conditionsChar);
132 if (
$name eq
'parameters') {
133 $expat->setHandlers( Char=> \&Text, Start => \&StartTag );
139 my ($expat, $text) = @
_;
140 if ($expat->in_element(
'value') || $expat->in_element(
'icon-link')) {
142 $weatherdata{$timestr}->{$currLbl} = $text;
152 my ($expat, $text) = @
_;
153 if ($expat->in_element(
'layout-key')) {
158 if ($expat->in_element(
'start-valid-time')) {
159 # yea, putting it into almost the same format, the reason for this that
160 # you can't get a date out of UnixDate that has tz in 0:00 format,
166 $expat->{CurrStartTime} = $text;
168 if ($expat->in_element(
'end-valid-time')) {
177 ########## Exported method to do parsing #################
181 my $product =
"time-series";
184 SOAP::Data->
name(
"longitude" =>
$lon),
185 SOAP::Data->
name(
"product" => $product),
186 SOAP::Data->
name(
"startTime" => $start),
187 SOAP::Data->
name(
"endTime" => $end),
189 SOAP::Data->
name(
"weatherParameters" =>
191 SOAP::Data->
type(
'boolean')->
name(
"maxt" => $params->{maxt}),
192 SOAP::Data->
type(
'boolean')->
name(
"mint" => $params->{mint}),
193 SOAP::Data->
type(
'boolean')->
name(
"temp" => $params->{temp}),
194 SOAP::Data->
type(
'boolean')->
name(
"dew" => $params->{dew}),
195 SOAP::Data->
type(
'boolean')->
name(
"pop12" => $params->{pop12}),
196 SOAP::Data->
type(
'boolean')->
name(
"qpf" => $params->{qpf}),
197 SOAP::Data->
type(
'boolean')->
name(
"sky" => $params->{sky}),
198 SOAP::Data->
type(
'boolean')->
name(
"snow" => $params->{snow}),
199 SOAP::Data->
type(
'boolean')->
name(
"wspd" => $params->{wspd}),
200 SOAP::Data->
type(
'boolean')->
name(
"wdir" => $params->{wdir}),
201 SOAP::Data->
type(
'boolean')->
name(
"wx" => $params->{wx}),
202 SOAP::Data->
type(
'boolean')->
name(
"waveh" => $params->{waveh}),
203 SOAP::Data->
type(
'boolean')->
name(
"icons" => $params->{icons}),
204 SOAP::Data->
type(
'boolean')->
name(
"rh" => $params->{rh}),
205 SOAP::Data->
type(
'boolean')->
name(
"appt" => $params->{appt}))));
207 my $parser =
new XML::Parser(Style =>
'Stream');
208 $parser->parse(
"$NDFD_XML");