package Protocol::Yadis::Document; use strict; use warnings; use overload '""' => sub { shift->to_string }, fallback => 1; use Protocol::Yadis::Document::Service; use Protocol::Yadis::Document::Service::Element; use XML::LibXML; sub new { my $class = shift; my %param = @_; my $self = {}; bless $self, $class; $self->{_services} ||= []; return $self; } sub services { my $self = shift; if (@_) { $self->{_services} = []; return $self; } else { my @priority = grep { defined $_->attr('priority') } @{$self->{_services}}; my @other = grep { not defined $_->attr('priority') } @{$self->{_services}}; my @sorted = sort { $a->attr('priority') cmp $b->attr('priority') } @priority; push @sorted, @other; return [@sorted]; } return $self->{_services}; } sub parse { my $class = shift; my $document = shift; my $self = $class->new; return unless $document; my $parser = XML::LibXML->new; my $doc; eval {$doc = $parser->parse_string($document); }; return if $@; # Get XRDS my $xrds = shift @{$doc->getElementsByTagName('xrds:XRDS')}; $xrds = shift @{$doc->getElementsByTagName('XRDS')} unless $xrds; return unless $xrds; # Get /last/ XRD my @xrd = $xrds->getElementsByTagName('XRD'); my $xrd = $xrd[-1]; return unless $xrd; my $services = []; my @services = $xrd->getElementsByTagName('Service'); foreach my $service (@services) { my $s = Protocol::Yadis::Document::Service->new(attrs => [map { $_->getName => $_->getValue } $service->attributes]); my $elements = []; my @nodes = $service->childNodes; foreach my $node (@nodes) { next unless $node->isa('XML::LibXML::Element'); my @attrs = $node->attributes; my $content = $node->textContent; $content =~ s/^\s*//s; $content =~ s/\s*$//s; my $element = Protocol::Yadis::Document::Service::Element->new( name => $node->getName, content => $content, attrs => [map { $_->getName => $_->getValue } @attrs] ); push @$elements, $element; } $s->elements($elements); next unless $s->Type; push @{$self->{_services}}, $s; } return $self; } sub to_string { my $self = shift; my $string = ''; $string .= '' . "\n"; $string .= ' services}) { $string .= $service->to_string; } $string .= " \n"; $string .= "\n"; return $string; } 1; __END__ =head1 NAME Protocol::Yadis::Document - Protocol::Yadis document object =head1 SYNOPSIS my $d = Protocol::Yadis::Document->parse(< http://lid.netmesh.org/sso/2.0 http://lid.netmesh.org/sso/1.0 my $services = $d->services; =head1 DESCRIPTION This is a document object for L. =head1 METHODS =head2 C Creates a new L instance. =head2 C Returns discovered Yadis services. =head2 C Parses XML document. =head2 C String representation. =head1 AUTHOR Viacheslav Tykhanovskyi, C. =head1 COPYRIGHT Copyright (C) 2009, Viacheslav Tykhanovskyi. This program is free software, you can redistribute it and/or modify it under the same terms as Perl 5.10. =cut