/usr/local/CPAN/MooseX-DOM/MooseX/DOM/Meta/LibXML.pm
# $Id: /mirror/coderepos/lang/perl/MooseX-DOM/trunk/lib/MooseX/DOM/Meta/LibXML.pm 68283 2008-08-12T02:34:53.003080Z daisuke $
package MooseX::DOM::Meta::LibXML;
use Moose;
extends 'Moose::Meta::Class';
has 'dom_root' => (
is => 'rw',
isa => 'HashRef',
default => sub { +{} }
);
has 'dom_attributes' => (
is => 'rw',
isa => 'HashRef',
default => sub { +{} }
);
has 'dom_children' => (
is => 'rw',
isa => 'HashRef',
default => sub { +{} }
);
__PACKAGE__->meta->make_immutable;
no Moose;
sub assert_root_node {
my ($self, $object, $node) = @_;
my $tag = $self->dom_root->{tag};
$node ||= $object->node;
if ($node && $node->getName ne $tag) {
confess "given node does not have required root node $tag";
}
}
sub create_root_node {
my ($self, $object) = @_;
return if $object->node;
my $root = $self->dom_root;
confess "No root node defined" unless $root;
my $tag = $root->{tag};
my $attrs = $root->{attributes};
my $doc = XML::LibXML::Document->new( '1.0' => 'UTF-8' );
my $node = $doc->createElement($tag);
while (my($name, $value) = each %$attrs) {
$node->setAttribute($name, $value);
}
$node = MooseX::DOM::LibXML::ContextNode->new(node => $node);
$object->node( $node );
return $node;
}
sub register_dom_attribute {
my ($self, $name) = @_;
$self->dom_attributes->{$name}++;
}
sub register_dom_child {
my ($self, $name, $spec) = @_;
$self->dom_children->{$name} = $spec;
}
sub get_dom_attribute {
my ($self, $object, $name) = @_;
my $node = $object->node;
return () unless $node;
$node->getAttribute($name);
}
sub set_dom_attribute {
my ($self, $object, $name, $value) = @_;
my $node = $object->node;
if (! $node) {
$node = $self->create_root_node( $object );
}
$node->setAttribute($name, $value);
}
sub get_dom_children {
my ($self, $object, $name) = @_;
my $node = $object->node;
return () unless $node;
my $spec = $self->dom_children->{ $name };
return () unless $spec;
my $tagname = $spec->{tag} || $name;
my $nsuri = $spec->{namespace} ? $object->namespaces->{ $spec->{namespace} } : undef;
my @children = ($nsuri) ?
$node->getChildrenByTagNameNS($nsuri, $tagname):
$node->getChildrenByTagName($tagname)
;
return $spec->{filter}->( $object, @children );
}
sub set_dom_children {
my ($self, $object, $name, @args) = @_;
my $node = $object->node;
if (! $node) {
$node = $self->create_root_node( $object );
}
my $spec = $self->dom_children->{ $name };
return () unless $spec;
my $tagname = $spec->{tag};
my $nsuri = $spec->{namespace} ? $object->namespaces->{ $spec->{namespace} } : undef;
my @children = ($nsuri) ?
$node->getChildrenByTagNameNS($nsuri, $tagname):
$node->getChildrenByTagName($tagname)
;
$node->removeChild($_) for @children;
return $spec->{create}->( $object, tag => $tagname, namespace => $spec->{namespace}, values => \@args );
}
1;