File Coverage

blib/lib/EPUB/Parser/File/Parser.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             package EPUB::Parser::File::Parser;
2 14     14   4489 use strict;
  14         132  
  14         299  
3 14     14   40 use warnings;
  14         16  
  14         227  
4 14     14   36 use Carp;
  14         12  
  14         504  
5 14     14   42 use Smart::Args;
  14         12  
  14         448  
6 14     14   12918 use XML::LibXML;
  0            
  0            
7             use XML::LibXML::XPathContext;
8              
9             use constant CONTEXT_XPATH => {
10             metadata => '/pkg:package/pkg:metadata',
11             manifest => '/pkg:package/pkg:manifest',
12             spine => '/pkg:package/pkg:spine',
13             guide => '/pkg:package/pkg:guide',
14             toc => '/xhtml:html/xhtml:body/xhtml:nav[@id="toc"]',
15             };
16              
17             sub new {
18             args(
19             my $class => 'ClassName',
20             my $data,
21             );
22              
23             my $xml = XML::LibXML->new({ no_network => 1, recover => 1 });
24             my $xml_document = $xml->parse_string($data);
25             my $xpath = XML::LibXML::XPathContext->new($xml_document);
26              
27             my $self = bless {
28             parser => $xpath,
29             doc => $xml_document,
30             current_context_key => '',
31             } => $class;
32              
33             return $self;
34             }
35              
36             sub context_node {
37             my $self = shift;
38             my $key = shift;
39              
40             return $self->{parser}->getContextNode unless $key;
41              
42             if ( $self->{current_context_key} ne $key ) {
43              
44             croak "did not match key($key) in CONTEXT_XPATH()" unless my $xpath = CONTEXT_XPATH()->{$key};
45              
46             my $nodes = $self->{parser}->findnodes($xpath);
47             my $context_node;
48             if ( $nodes->size >= 1 ) {
49             $context_node = $nodes->get_node(1);
50             }
51              
52             croak '$context_node not found' unless $context_node;
53            
54             $self->{parser}->setContextNode($context_node);
55             $self->{current_context_key} = $key;
56             }
57              
58             return $self;
59             }
60              
61             sub _find {
62             my $self = shift;
63             my $xpath = shift or croak 'please input xpath';
64             my $node = shift || $self->context_node;
65              
66             $node ? $self->{parser}->findnodes($xpath, $node)
67             : $self->{parser}->findnodes($xpath);
68             }
69              
70             sub find {
71             my $self = shift;
72             $self->_find(@_);
73             }
74              
75             sub single {
76             my $self = shift;
77             my $node_list = $self->_find(@_);
78             if ( $node_list->size >= 1 ) {
79             $node_list->get_node(1);
80             }
81             }
82              
83              
84             1;