package Catmandu::Fix::xml_simple; our $VERSION = '0.17'; use Catmandu::Sane; use Moo; use XML::Struct::Reader; use XML::LibXML::Reader; use Catmandu::Fix::Has; with 'Catmandu::Fix::Base'; # TODO: avoid code duplication with xml_read has field => ( fix_arg => 1 ); has attributes => ( fix_opt => 1 ); has ns => ( fix_opt => 1 ); has content => ( fix_opt => 1 ); has root => ( fix_opt => 1 ); has depth => ( fix_opt => 1 ); has path => ( fix_opt => 1 ); has whitespace => ( fix_opt => 1 ); sub simple { 1 } has _reader => ( is => 'ro', lazy => 1, builder => sub { XML::Struct::Reader->new( map { $_ => $_[0]->$_ } grep { defined $_[0]->$_ } qw(attributes ns simple root depth content whitespace) ); } ); sub emit { my ( $self, $fixer ) = @_; my $path = $fixer->split_path( $self->field ); my $key = pop @$path; my $reader = $fixer->capture( $self->_reader ); my $xpath = $fixer->capture( $self->path ); my $attributes = $fixer->capture( $self->attributes ); # TODO: use XML::Struct::Simple instead my $options = $fixer->capture( { map { $_ => $self->$_ } grep { defined $self->$_ } qw(root depth attributes) } ); return $fixer->emit_walk_path( $fixer->var, $path, sub { my $var = $_[0]; $fixer->emit_get_key( $var, $key, sub { my $var = $_[0]; return <new( string => ${var} ); ${var} = ${xpath} ? [ ${reader}->readDocument(\$stream, ${xpath}) ] : ${reader}->readDocument(\$stream); } PERL } ); } ); } 1; __END__ =head1 NAME Catmandu::Fix::xml_simple - parse/convert XML to key-value form =head1 SYNOPSIS xml_read(xml) xml_simple(xml) xml_read(xml, simple=1) # equivalent =head1 DESCRIPTION This L transforms MicroXML or parses XML strings to key-value form with L. =head1 OPTIONS See L for parsing options. =cut