File Coverage

blib/lib/CFDI/Location/XPath.pm
Criterion Covered Total %
statement 6 52 11.5
branch 0 34 0.0
condition 0 30 0.0
subroutine 2 4 50.0
pod 0 2 0.0
total 8 122 6.5


line stmt bran cond sub pod time code
1             package CFDI::Location::XPath;
2 1     1   5 use strict;
  1         2  
  1         23  
3 1     1   4 use CFDI::Constants::Class;
  1         2  
  1         472  
4             require Exporter;
5             our @EXPORT = qw(xpath);
6             our @ISA = qw(Exporter);
7             our $VERSION = 0.4;
8              
9             sub new{
10 0     0 0   my $invocant = shift;
11 0   0       my $class = ref $invocant || $invocant;
12 0           my $content = shift;
13 0 0 0       return unless defined $content && ref $content eq CONTENT;
14 0           bless {_current=>'/',_rootRef=>$content,_currentRef=>$content},$class;
15             }
16              
17             sub xpath($_){
18 0 0   0 0   return unless $#_ == 1;
19 0           local $_;
20 0           my $self;
21 0 0 0       $_[0] && ref $_[0] ? ($self,$_) : ($_,$self) = @_;
22 0 0 0       return unless defined && !ref && length;
      0        
23 0 0 0       return unless defined $self && $self->isa(__PACKAGE__);
24 0           my $abs = ord '/' eq ord;
25 0 0         substr $_,0,1,'' if $abs;
26 0           my @path = m!([^/]+)!g;
27 0           my $xpath;
28 0           my ($hasAttr,$attr);
29 0           while(@path){
30 0           local $_ = shift @path;
31 0 0         if(/@/){
32 0           $hasAttr = 1;
33 0 0         $attr = $1 if /^@(.*)/;
34 0           last;
35             }else{
36 0           $xpath .= "/$_";
37             }
38             }
39 0 0         return unless $#path == -1;
40 0 0 0       return if $hasAttr && !defined $attr;
41 0           @path = $xpath =~ m!([^/]+)!g;
42 0           my ($refPath,$foundPath,$element) = ($$self{_rootRef},'');
43 0           while(@path){
44 0 0 0       last unless defined $refPath && ref $refPath eq CONTENT;
45 0           my $elementName = shift @path;
46 0   0       my @elements = grep ref eq ELEMENT && ${$$_[0]} eq $elementName,@$refPath;
47 0 0         last unless @elements;
48 0           $element = shift @elements;
49 0           $foundPath .= "/$elementName";
50 0           my @contents = grep ref eq CONTENT,@$element;
51 0 0         last unless @contents;
52 0           $refPath = shift @contents;
53             }
54 0 0 0       return unless $#path == -1 && $foundPath eq $xpath;
55 0 0         if($attr){
56 0 0         return unless defined $element;
57 0           my @attributes = grep ref eq ATTRIBUTES,@$element;
58 0 0         return unless @attributes;
59 0           my %attr = @{shift @attributes};
  0            
60 0           return $attr{$attr};
61             }else{
62 0           return $refPath;
63             }
64             }
65              
66             1;