Skip to content

Commit

Permalink
added method readDocument
Browse files Browse the repository at this point in the history
  • Loading branch information
nichtich committed Sep 11, 2013
1 parent 144b2ea commit 149a638
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 9 deletions.
8 changes: 4 additions & 4 deletions lib/XML/Struct.pm
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,19 @@ our @EXPORT_OK = qw(readXML writeXML hashifyXML textValues);
sub readXML { # ( [$from], %options )
my (%options) = @_ % 2 ? (from => @_) : @_;

my %reader = (
my %reader_options = (
map { $_ => delete $options{$_} }
grep { exists $options{$_} } qw(attributes whitespace path stream hashify root)
);
if (%options) {
if (exists $options{from} and keys %options == 1) {
$reader{from} = $options{from};
$reader_options{from} = $options{from};
} else {
$reader{from} = \%options;
$reader_options{from} = \%options;
}
}

XML::Struct::Reader->new( %reader )->read;
XML::Struct::Reader->new( %reader_options )->readDocument;
}

sub writeXML {
Expand Down
23 changes: 22 additions & 1 deletion lib/XML/Struct/Reader.pm
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ C<//>, no node tests...). Namespaces are not supported yet.
Include ignorable whitespace as text elements (disabled by default)
=method read = readNext ( $stream [, $path ] )
=method read = readNext ( [ $stream ] [, $path ] )
Read the next XML element from a stream. If no path option is specified, the
reader's path option is used ("C<*>" by default, first matching the root, then
Expand Down Expand Up @@ -168,6 +168,27 @@ sub readNext { # TODO: use XML::LibXML::Reader->nextPatternMatch for more perfor

*read = \&readNext;

=method readDocument( [ $stream ] [, $path ] )
Read an entire XML document. In contrast to C<read>/C<readNext>, this method
always reads the entire stream. The return value is the first element (that is
the root element by default) in scalar context and a list of elements in array
context. Multiple elements can be returned for instance when a path was
specified to select document fragments.
=cut

sub readDocument {
my $self = shift;
my @document;

while(my $element = $self->read(@_)) {
push @document, $element;
}

return wantarray ? @document : $document[0];
}

=method readElement( [ $stream ] )
Read an XML element from a stream and return it as array reference with element name,
Expand Down
10 changes: 6 additions & 4 deletions t/reader.t
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,12 @@ is_deeply readXML( 't/flat.xml', hashify => 1, root => 1, attributes => 0 ),
{ doc => { id => [1,2,4], xx => 3 } },
'hashify with root and without attributes';

#note explain readXML( 't/flat.xml', path => '/doc/id', hashify => 1, root => 'foo' );
my @nodes = readXML( 't/flat.xml', path => '/doc/id', hashify => 1, root => 'xx' );
is_deeply \@nodes, [ { xx => 1 }, { xx => 2 }, { xx => 4 } ], 'list of nodes';

#is_deeply readXML( 't/flat.xml', path => '/doc/id', hashify => 1, root => 1, attributes => 0 ),
# { id => [1,2,4] },
# 'hashify with path and root';
my $first = readXML( 't/flat.xml', path => '/doc/id', hashify => 1, root => 'xx' );
is_deeply $first, { xx => 1 }, 'first of a list of nodes';

# TODO: test as loop

done_testing;

0 comments on commit 149a638

Please sign in to comment.