SOLVED in the update at the end.
I need to parse a continuous XML stream coming from a device via http. The problem I run into is I can't find a way to convince PerlSAX to take a URL as a source. There's no good way to "download" the XML and hand it off to the XML parser because the download is never going to finish (continuous stream).
# This is the URL that streams alerts such as motion detection. Docume
+ntation at goo.gl/S38ZQq
my($url) = "http://".$user.":".$password."@".$ip.":".$port."/ISAPI/Eve
+nt/notification/alertStream";
#start an instance of SAX parser for each monitor
my $handler = SAXAlertStreamHandler->new();
my $parser = XML::Parser::PerlSAX->new( Handler => $handler );
my %parser_args = (Source => {SystemId => $url});
$parser->parse(%parser_args);
exit;
Couldn't open http://user:password@10.1.10.23:80/ISAPI/Event/notificat
+ion/alertStream:
No such file or directory at /usr/local/share/perl/5.18.2/XML/Parser/P
+erlSAX.pm line 146.
Update: Based on the great information found here, I did determine that preprocessing the data was required. LWP has the ability to process with a handler. As a really nice side-effect, the LWP handler seems to automatically call the handler for each part of the multpart stream so I don't need to set the read_size_hint. For even better multipart http handling, see Alexander's MultipartFilter.pm module.
Below is my working code
#!/usr/bin/perl
use XML::Twig;
use warnings;
use strict;
use LWP;
my $url =
'http://username:password@10.0.0.1/Event/notification/alertStream';
my $browser = LWP::UserAgent->new();
my $twig =
new XML::Twig(
twig_handlers => { EventNotificationAlert => \&AlertStreamHandler
+} );
my $response = $browser->get(
$url,
':content_cb' => \&raw_handler,
':read_size_hint' => 1024,
);
sub raw_handler {
my ( $data, $response ) = @_;
unless ( $data =~ /^--boundary/ ) {
$twig->parse($data);
#print $data;
}
}
sub AlertStreamHandler {
my ( $twig, $eventAlert ) = @_;
my $ip = $eventAlert->first_child('ipAddress')->text;
my $eventType = $eventAlert->first_child('eventType')->text;
print "IP: " . $ip . "\n";
print "Event: " . $eventType . "\n";
$twig->purge; # delete the twig so far
+. Not sure if this is needed.
}
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.
|