File Coverage

lib/Spreadsheet/XLSX/Reader/LibXML/XMLReader.pm
Criterion Covered Total %
statement 18 20 90.0
branch n/a
condition n/a
subroutine 7 7 100.0
pod n/a
total 25 27 92.5


line stmt bran cond sub pod time code
1             package Spreadsheet::XLSX::Reader::LibXML::XMLReader;
2             our $AUTHORITY = 'cpan:JANDREW';
3 5     5   1334080 use version; our $VERSION = qv('v0.38.18');
  5         11  
  5         41  
4              
5 5     5   645 use 5.010;
  5         16  
6 5     5   24 use Moose;
  5         6  
  5         34  
7 5     5   32393 use MooseX::StrictConstructor;
  5         58010  
  5         40  
8 5     5   26819 use MooseX::HasDefaults::RO;
  5         14321  
  5         37  
9 5         68 use Types::Standard qw(
10             Int HasMethods Bool
11             Num Str
12 5     5   32356 );
  5         11  
13 5     5   11564 use XML::LibXML::Reader;
  0            
  0            
14             use Data::Dumper;
15             use Carp 'confess';
16             use lib '../../../../../lib',;
17             ###LogSD with 'Log::Shiras::LogSpace';
18             ###LogSD use Log::Shiras::Telephone;
19             ###LogSD use Log::Shiras::UnhideDebug;
20             use Spreadsheet::XLSX::Reader::LibXML::Types qw(
21             IOFileType
22             );
23             use Spreadsheet::XLSX::Reader::LibXML::Error;
24              
25             #########1 Public Attributes 3#########4#########5#########6#########7#########8#########9
26              
27             has file =>(
28             isa => IOFileType,
29             reader => 'get_file',
30             writer => 'set_file',
31             predicate => 'has_file',
32             clearer => 'clear_file',
33             coerce => 1,
34             required => 1,
35             trigger => \&_build_xml_reader,
36             handles => [ 'close' ],
37             );
38              
39             has error_inst =>(
40             isa => HasMethods[qw(
41             error set_error clear_error set_warnings if_warn
42             ) ],
43             clearer => '_clear_error_inst',
44             reader => '_get_error_inst',
45             required => 1,
46             handles =>[ qw(
47             error set_error clear_error set_warnings if_warn
48             ) ],
49             default => sub{ Spreadsheet::XLSX::Reader::LibXML::Error->new },
50             );
51              
52             has xml_version =>(
53             isa => Num,
54             reader => 'version',
55             writer => '_set_xml_version',
56             clearer => '_clear_xml_version',
57             );
58              
59             has xml_encoding =>(
60             isa => Str,
61             reader => 'encoding',
62             predicate => 'has_encoding',
63             writer => '_set_xml_encoding',
64             clearer => '_clear_xml_encoding',
65             );
66              
67             has xml_header =>(
68             isa => Str,
69             reader => 'get_header',
70             writer => '_set_xml_header',
71             );
72              
73             has position_index =>(
74             isa => Int,
75             reader => 'where_am_i',
76             writer => 'i_am_here',
77             clearer => 'clear_location',
78             predicate => 'has_position',
79             );
80              
81             #########1 Public Methods 3#########4#########5#########6#########7#########8#########9
82              
83              
84             sub start_the_file_over{
85             my( $self, ) = @_;
86             ###LogSD my $phone = Log::Shiras::Telephone->new( name_space =>
87             ###LogSD $self->get_all_space . '::XMLReader::FromFile::start_the_file_over', );
88             if( $self->has_file ){
89             ###LogSD $phone->talk( level => 'debug', message =>[ "Resetting the XML file" ] );
90             #~ $self->_go_to_the_end;
91             $self->_close_the_sheet;
92             #~ $self->_clear_xml_parser;
93             $self->clear_location;
94             my $fh = $self->get_file;
95             $fh->seek( 0, 0 );
96             $self->_set_xml_parser( XML::LibXML::Reader->new( IO => $fh ) );
97             return 1;
98             }else{
99             ###LogSD $phone->talk( level => 'info', message =>[ "No file to reset" ] );
100             return undef;
101             }
102             }
103              
104             sub get_text_node{
105             my ( $self, ) = @_;
106             ###LogSD my $phone = Log::Shiras::Telephone->new( name_space =>
107             ###LogSD $self->get_all_space . '::XMLReader::get_text_node', );
108             ###LogSD $phone->talk( level => 'debug', message => [
109             ###LogSD "getting the text value of the node", ] );
110            
111             # Check for a text node type (and return immediatly if so)
112             if( $self->_has_value ){
113             my $node_text = $self->_node_value;
114             ###LogSD $phone->talk( level => 'debug', message =>[
115             ###LogSD "This is a text node - returning value: $node_text",] );
116             return ( 1, $node_text, );
117             }
118             # Return undef for no value
119             return ( undef,);
120             }
121              
122             sub get_attribute_hash_ref{
123             my ( $self, ) = @_;
124             ###LogSD my $phone = Log::Shiras::Telephone->new( name_space =>
125             ###LogSD $self->get_all_space . '::XMLReader::get_attribute_hash_ref', );
126             ###LogSD $phone->talk( level => 'debug', message => [
127             ###LogSD "Extract all attributes as a hash ref", ] );
128            
129             my $attribute_ref = {};
130             my $result = $self->_move_to_first_att;
131             ###LogSD $phone->talk( level => 'trace', message =>[
132             ###LogSD "Result of the first attribute move: $result",] );
133             ATTRIBUTELIST: while( $result > 0 ){
134             my $att_name = $self->_node_name;
135             my $att_value = $self->_node_value;
136             ###LogSD $phone->talk( level => 'debug', message => [
137             ###LogSD "Reading attribute: $att_name", "..and value: $att_value" ] );
138             if( $att_name eq 'val' ){
139             $attribute_ref = $att_value;
140             ###LogSD $phone->talk( level => 'debug', message => [
141             ###LogSD "Assuming we are at the bottom of the attribute list with a found attribute val: $att_value"] );
142             last ATTRIBUTELIST;
143             }else{
144             $attribute_ref->{$att_name} = "$att_value";
145             }
146             $result = $self->_move_to_next_att;
147             ###LogSD $phone->talk( level => 'debug', message => [
148             ###LogSD "Result of the move: $result", ] );
149             }
150             $result = ( ref $attribute_ref ) ? (keys %$attribute_ref) : 1;
151             ###LogSD $phone->talk( level => 'debug', message => [
152             ###LogSD "Returning attribute ref:", $attribute_ref ] );
153             return ( $result, $attribute_ref );
154             }
155              
156             sub advance_element_position{
157             my ( $self, $element, $position ) = @_;
158             if( $position and $position < 1 ){
159             confess "You can only advance element position in a positive direction, |$position| is not correct.";
160             }
161             $position ||= 1;
162             ###LogSD my $phone = Log::Shiras::Telephone->new( name_space =>
163             ###LogSD $self->get_all_space . '::XMLReader::advance_element_position', );
164             ###LogSD $phone->talk( level => 'debug', message => [
165             ###LogSD "Advancing to element -" . ($element//'') . "- -$position- times", ] );
166             my ( $result, $node_depth, $node_name, $node_type, $byte_count );
167             my $x = 0;
168             for my $y ( 1 .. $position ){
169             ###LogSD $phone->talk( level => 'debug', message => [
170             ###LogSD "Advancing position case: $y", ] );
171             if( defined $element ){
172             ###LogSD $phone->talk( level => 'debug', message => [
173             ###LogSD "Searching for element: $element", ] );
174             $result = $self->_next_element( $element );
175             }else{
176             ###LogSD $phone->talk( level => 'debug', message => [
177             ###LogSD "Indexing one more generic node", ] );
178             ( $result, my( $node_depth, $node_name, $node_type ) ) = $self->_next_node;
179             ###LogSD $phone->talk( level => 'debug', message => [
180             ###LogSD "Received the result: $result", "..at depth: $node_depth",
181             ###LogSD "..and node named: $node_name", "..of node type: $node_type" ] );
182            
183             # Climb out of end tags
184             while( $result and $node_type == 15 ){
185             ###LogSD $phone->talk( level => 'debug', message => [
186             ###LogSD "Advancing from end node", ] );
187             ( $result, $node_depth, $node_name, $node_type ) = $self->_next_node;
188             ###LogSD $phone->talk( level => 'debug', message => [
189             ###LogSD "Received the result: $result", "..at depth: $node_depth",
190             ###LogSD "..and node named: $node_name", "..of node type: $node_type" ] );
191             }
192             }
193             last if !$result;
194             $x++;
195             }
196             if( defined $node_type and $node_type == 0 ){
197             ###LogSD $phone->talk( level => 'info', message =>[ "Reached the end of the file!" ] );
198             }elsif( !$result ){
199             ###LogSD $phone->talk( level => 'info', message =>[
200             ###LogSD "Unable to location position -$position- for element: " . ($element//'') ] );
201             }else{
202             ###LogSD $phone->talk( level => 'debug', message => [
203             ###LogSD "Actually advanced -$x- positions with result: $result",
204             ###LogSD "..indicated by:", $self->location_status ] );
205             }
206             return $result;
207             }
208              
209             sub location_status{
210             my ( $self, ) = @_;
211             ###LogSD my $phone = Log::Shiras::Telephone->new( name_space =>
212             ###LogSD $self->get_all_space . '::XMLReader::location_status', );
213             ###LogSD $phone->talk( level => 'debug', message => [
214             ###LogSD "Getting the status for the current position", ] );
215             my ( $node_depth, $node_name, $node_type ) = ( $self->_node_depth, $self->_node_name, $self->_node_type );
216             $node_name =
217             ( $node_type == 0 ) ? 'EOF' :
218             ( $node_name eq '#text') ? 'raw_text' :
219             $node_name;
220             ###LogSD $phone->talk( level => 'debug', message => [
221             ###LogSD "Currently at libxml2 level: $node_depth",
222             ###LogSD "Current node name: $node_name",
223             ###LogSD "..for type: $node_type" ] );
224             return ( $node_depth, $node_name, $node_type );
225             }
226            
227              
228             #########1 Private Attributes 3#########4#########5#########6#########7#########8#########9
229              
230             has _xml_reader =>(
231             isa => 'XML::LibXML::Reader',
232             reader => '_get_xml_parser',
233             writer => '_set_xml_parser',
234             predicate => '_has_xml_parser',
235             clearer => '_clear_xml_parser',
236             handles =>{
237             copy_current_node => 'copyCurrentNode',
238             _close_the_sheet => 'close',
239             _node_depth => 'depth',
240             _node_type => 'nodeType',
241             _node_name => 'name',
242             _encoding => 'encoding',
243             _version => 'xmlVersion',
244             _next_element => 'nextElement',
245             _node_value => 'value',
246             _has_value => 'hasValue',
247             _move_to_first_att => 'moveToFirstAttribute',
248             _move_to_next_att => 'moveToNextAttribute',
249             _read_next_node => 'read',
250             #~ _go_to_the_end => 'finish',
251             #~ get_node_all => 'readOuterXml',
252             },
253             trigger => \&_reader_init,
254             );
255              
256             has _read_unique_bits =>(
257             isa => Bool,
258             reader => '_get_unique_bits',
259             writer => '_need_unique_bits',
260             clearer => '_clear_read_unique_bits',
261             default => 1,
262             );
263              
264             #########1 Private Methods 3#########4#########5#########6#########7#########8#########9
265              
266             sub _next_node{
267             my( $self, ) = @_;
268             ###LogSD my $phone = Log::Shiras::Telephone->new( name_space =>
269             ###LogSD $self->get_all_space . '::XMLReader::_next_node', );
270             ###LogSD $phone->talk( level => 'debug', message => [
271             ###LogSD "Reading the next node in the xml document", ] );
272             my $result = eval{ $self->_read_next_node } ? 1 : 0 ;# Handle unclosed xml tags without dying
273             ###LogSD $phone->talk( level => 'debug', message => [
274             ###LogSD "Result of the read: $result", ] );
275             my ( $node_depth, $node_name, $node_type ) = $self->location_status;
276             if( $node_name eq '#document' and $node_depth == 0 ){
277             ###LogSD $phone->talk( level => 'debug', message => [
278             ###LogSD "Reached the unexpected end of the document", ] );
279             $result = 0;
280             }
281            
282             if( wantarray ){
283             ###LogSD $phone->talk( level => 'debug', message => [
284             ###LogSD "Returning the result: $result", "..at depth: $node_depth",
285             ###LogSD "..to node named: $node_name", "..and node type: $node_type" ] );
286             return( $result, $node_depth, $node_name, $node_type );
287             }else{
288             ###LogSD $phone->talk( level => 'debug', message => [
289             ###LogSD "Returning the result: $result", ] );
290             return $result;
291             }
292             }
293              
294             #~ around BUILDARGS => sub {
295             #~ my ( $orig, $class, %args ) = @_;
296             #~ ###LogSD my $log_space = $args{log_space};
297             #~ ###LogSD $log_space .= '::' if $log_space;
298             #~ ###LogSD $log_space .= 'Workbook::BUILDARGS';
299             #~ confess "----------Dumping at BUILDARGS:" . $class->meta->dump(5);
300             #~ ###LogSD my $phone = Log::Shiras::Telephone->new(
301             #~ ###LogSD name_space => $log_space, );
302             #~ ###LogSD $phone->talk( level => 'trace', message =>[
303             #~ ###LogSD 'Arrived at BUILDARGS with: ', %args ] );
304             #~ my $orig = shift;
305             #~ my $class = shift;
306            
307             #~ if ( @_ == 1 && !ref $_[0] ) {
308             #~ return $class->$orig( ssn => $_[0] );
309             #~ }
310             #~ else {
311             #~ return $class->$orig(@_);
312             #~ }
313             #~ };
314              
315             sub _reader_init{
316             my( $self, $reader ) = @_;
317             ###LogSD my $phone = Log::Shiras::Telephone->new( name_space =>
318             ###LogSD $self->get_all_space . '::XMLReader::_reader_init', );
319             ###LogSD $phone->talk( level => 'debug', message => [
320             ###LogSD "loading any file specific settings", ] );
321            
322             if( $self->_get_unique_bits ){
323             ###LogSD $phone->talk( level => 'debug', message => [
324             ###LogSD "loading any file specific settings - since this is the first open", ] );
325             $self->_need_unique_bits( 0 );
326            
327             # Set basic xml values
328             my $xml_string = '<?xml version="';
329             $self->_next_node;
330             if( $self->_version ){
331             $self->_set_xml_version( $self->_version );
332             $xml_string .= $self->_version . '"';
333             }else{
334             confess "Could not find the version of this xml document!";
335             }
336             if( $self->_encoding ){
337             $self->_set_xml_encoding( $self->_encoding );
338             $xml_string = ' encoding="' . $self->_encoding . '"'
339             }else{
340             $self->_clear_xml_encoding;
341             }
342             $xml_string .= '?>';
343             $self->_set_xml_header( $xml_string );
344            
345             # Set the file unique bits
346             ###LogSD $phone->talk( level => 'debug', message =>[
347             ###LogSD "Check if this type of file has unique settings" ], );
348             if( $self->can( '_load_unique_bits' ) ){
349             ###LogSD $phone->talk( level => 'debug', message =>[ "Loading unique bits" ], );
350             $self->_load_unique_bits;
351             ###LogSD $phone->talk( level => 'debug', message =>[
352             ###LogSD "Finished loading unique bits" ], );
353             }
354             $self->start_the_file_over;
355             }else{
356             ###LogSD $phone->talk( level => 'debug', message =>[
357             ###LogSD "This is not the first time the file has been opened - don't reload settings" ], );
358             }
359             ###LogSD $phone->talk( level => 'debug', message => [ "Finished the file initialization" ], );
360             }
361              
362             sub _build_xml_reader{
363             my( $self, $file_handle ) = @_;
364             ###LogSD my $phone = Log::Shiras::Telephone->new( name_space =>
365             ###LogSD $self->get_all_space . '::XMLReader::_build_xml_reader', );
366             ###LogSD $phone->talk( level => 'debug', message => [
367             ###LogSD "turning a file handle into an xml reader", ] );
368            
369             # Build the reader
370             $file_handle->seek( 0, 0 );
371             my $xml_reader = XML::LibXML::Reader->new( IO => $file_handle );
372             $xml_reader->read;
373             ###LogSD $phone->talk( level => 'debug', message =>[ 'Loading reader:', $xml_reader ], );
374             $self->_set_xml_parser( $xml_reader );
375             ###LogSD $phone->talk( level => 'debug', message => [ "Finished loading XML reader" ], );
376             }
377              
378             sub DEMOLISH{
379             my ( $self ) = @_;
380             ###LogSD my $phone = Log::Shiras::Telephone->new( name_space =>
381             ###LogSD $self->get_all_space . '::XMLReader::DEMOLISH', );
382             ###LogSD $phone->talk( level => 'debug', message => [
383             ###LogSD "clearing the reader for log space:" . $self->get_log_space, ] );
384             if( $self->_get_xml_parser ){
385             #~ print "Disconnecting the sheet file handle from the parser\n";
386             ###LogSD $phone->talk( level => 'debug', message =>[ "Disconnecting the file handle from the xml parser", ] );
387             $self->_close_the_sheet;
388             $self->_clear_xml_parser;
389             }
390             }
391              
392             #########1 Phinish 3#########4#########5#########6#########7#########8#########9
393              
394             no Moose;
395            
396             1;
397              
398             #########1 Documentation 3#########4#########5#########6#########7#########8#########9
399             __END__
400              
401             =head1 NAME
402              
403             Spreadsheet::XLSX::Reader::LibXML::XMLReader - A LibXML::Reader xlsx base class
404              
405             =head1 SYNOPSIS
406              
407             package MyPackage;
408             use MooseX::StrictConstructor;
409             use MooseX::HasDefaults::RO;
410             extends 'Spreadsheet::XLSX::Reader::LibXML::XMLReader';
411            
412             =head1 DESCRIPTION
413              
414             This documentation is written to explain ways to use this module when writing your own excel
415             parser. To use the general package for excel parsing out of the box please review the
416             documentation for L<Workbooks|Spreadsheet::XLSX::Reader::LibXML>,
417             L<Worksheets|Spreadsheet::XLSX::Reader::LibXML::Worksheet>, and
418             L<Cells|Spreadsheet::XLSX::Reader::LibXML::Cell>
419              
420             This module provides a generic way to open an xml file or xml file handle and then extract
421             information using the L<XML::LibXML::Reader> parser. The additional methods and attributes
422             are intended to provide some coalated parsing commands that are specifically useful in turning
423             xml to perl data structures.
424              
425             =head2 Attributes
426              
427             Data passed to new when creating an instance. For modification of these attributes see the
428             listed 'attribute methods'. For general information on attributes see
429             L<Moose::Manual::Attributes>. For ways to manage the instance when opened see the
430             L<Methods|/Methods>.
431            
432             =head3 file
433              
434             =over
435              
436             B<Definition:> This attribute holds the file handle for the file being read. If the full
437             file name and path is passed to the attribute it is coerced to an IO::File file handle.
438              
439             B<Default:> no default - this must be provided to read a file
440              
441             B<Required:> yes
442              
443             B<Range:> any unencrypted xml file name and path or IO::File file handle
444              
445             B<attribute methods> Methods provided to adjust this attribute
446            
447             =over
448              
449             B<set_file>
450              
451             =over
452              
453             B<Definition:> change the file value in the attribute (this will reboot
454             the file instance and lock the file)
455              
456             =back
457              
458             B<get_file>
459              
460             =over
461              
462             B<Definition:> Returns the file handle of the file even if a file name
463             was passed
464              
465             =back
466              
467             B<has_file>
468              
469             =over
470              
471             B<Definition:> this is used to see if the file loaded correctly.
472              
473             =back
474              
475             B<clear_file>
476              
477             =over
478              
479             B<Definition:> this clears (and unlocks) the file handle
480              
481             =back
482              
483             =back
484              
485             L<Delegated Methods>
486              
487             =over
488              
489             B<close>
490              
491             =over
492              
493             closes the file handle
494              
495             =back
496              
497             =back
498              
499             =back
500              
501             =head3 error_inst
502              
503             =over
504              
505             B<Definition:> This attribute holds the L<error handler
506             |Spreadsheet::XLSX::Reader::LibXML::Error>.
507              
508             B<Default:> no default - this must be provided to read a file
509              
510             B<Required:> yes
511              
512             B<Range:> any object instance that can provide the required delegated methods.
513              
514             B<attribute methods> Methods provided to adjust this attribute
515              
516             =over
517              
518             B<_clear_error_inst>
519              
520             =over
521              
522             clear the attribute value
523              
524             =back
525              
526             =back
527              
528             B<_get_error_inst>
529              
530             =over
531              
532             get the attribute value
533              
534             =back
535              
536             =back
537              
538             B<Delegated Methods (required)> Methods delegated to this module by the attribute
539            
540             =over
541              
542             B<error>
543              
544             =over
545              
546             B<Definition:> returns the currently stored error string
547              
548             =back
549              
550             B<set_error>
551              
552             =over
553              
554             B<Definition:> Sets the error string
555              
556             =back
557              
558             B<clear_error>
559              
560             =over
561              
562             B<Definition:> clears the error string
563              
564             =back
565              
566             B<set_warnings>
567              
568             =over
569              
570             B<Definition:> Sets the state that determins if the instance pro-activly
571             warns with the error string when the error string is set.
572              
573             =back
574              
575             B<if_warn>
576              
577             =over
578              
579             B<Definition:> Returns the current state of the state value from 'set_warnings'
580              
581             =back
582              
583             =back
584              
585             =head3 xml_version
586              
587             =over
588              
589             B<Definition:> This stores the xml version stored in the xml header. It is read
590             when the file handle is first set in this sheet.
591              
592             B<Default:> no default - this is auto read from the header
593              
594             B<Required:> no
595              
596             B<Range:> xml versions
597              
598             B<attribute methods> Methods provided to adjust this attribute
599              
600             =over
601              
602             B<_clear_xml_version>
603              
604             =over
605              
606             clear the attribute value
607              
608             =back
609              
610             =back
611              
612             B<_set_xml_version>
613              
614             =over
615              
616             set the attribute value
617              
618             =back
619              
620             =back
621              
622             =head3 xml_encoding
623              
624             =over
625              
626             B<Definition:> This stores the data encoding of the xml file from the xml header.
627             It is read when the file handle is first set in this sheet.
628              
629             B<Default:> no default - this is auto read from the header
630              
631             B<Required:> no
632              
633             B<Range:> valid xml file encoding
634              
635             B<attribute methods> Methods provided to adjust this attribute
636              
637             =over
638              
639             B<encoding>
640              
641             =over
642              
643             get the attribute value
644              
645             =back
646              
647             =back
648              
649             =over
650              
651             B<has_encoding>
652              
653             =over
654              
655             predicate for the attribute value
656              
657             =back
658              
659             =back
660              
661             =over
662              
663             B<_clear_xml_encoding>
664              
665             =over
666              
667             clear the attribute value
668              
669             =back
670              
671             =back
672              
673             B<_set_xml_encoding>
674              
675             =over
676              
677             set the attribute value
678              
679             =back
680              
681             =back
682              
683             =head3 xml_header
684              
685             =over
686              
687             B<Definition:> This stores the xml header from the xml file. It is read when
688             the file handle is first set in this sheet.
689              
690             B<Default:> no default - this is auto read from the header
691              
692             B<Required:> no
693              
694             B<Range:> valid xml file header
695              
696             B<attribute methods> Methods provided to adjust this attribute
697              
698             =over
699              
700             B<get_header>
701              
702             =over
703              
704             get the attribute value
705              
706             =back
707              
708             =back
709              
710             =over
711              
712             B<_set_xml_header>
713              
714             =over
715              
716             set the attribute value
717              
718             =back
719              
720             =back
721              
722             =back
723              
724             =head3 position_index
725              
726             =over
727              
728             B<Definition:> This attribute is available to facilitate other consuming roles and
729             classes. Of the attribute methods only the 'clear_location' method is used in this
730             class during the 'start_the_file_over' method. It can be used for tracking same level
731             positions with the same node name.
732              
733             B<Default:> no default - this is mostly managed by the child class or add on role
734              
735             B<Required:> no
736              
737             B<Range:> Integer
738              
739             B<attribute methods> Methods provided to adjust this attribute
740              
741             =over
742              
743             B<where_am_i>
744              
745             =over
746              
747             get the attribute value
748              
749             =back
750              
751             =back
752              
753             =over
754              
755             B<i_am_here>
756              
757             =over
758              
759             set the attribute value
760              
761             =back
762              
763             =back
764              
765             =over
766              
767             B<clear_location>
768              
769             =over
770              
771             clear the attribute value
772              
773             =back
774              
775             =back
776              
777             =over
778              
779             B<has_position>
780              
781             =over
782              
783             set the attribute value
784              
785             =back
786              
787             =back
788              
789             =back
790              
791             =head2 Methods
792              
793             These are the methods provided by this class. They most likely should be agumented
794             with file specific methods when extending this module.
795              
796             =head3 start_the_file_over
797              
798             =over
799              
800             B<Definition:> This will disconnect the L<XML::LibXML::Reader> from the file handle,
801             rewind the file handle, and then reconnect the L<XML::LibXML::Reader> to the file handle.
802              
803             B<Accepts:> nothing
804              
805             B<Returns:> nothing
806              
807             =back
808              
809             =head3 get_text_node
810              
811             =over
812              
813             B<Definition:> This will collect the text node at the current node position. It will return
814             two items ( $success_or_failure, $text_node_value )
815              
816             B<Accepts:> nothing
817              
818             B<Returns:> ( $success_or_failure(1|undef), ($text_node_value|undef) )
819              
820             =back
821              
822             =head3 get_attribute_hash_ref
823              
824             =over
825              
826             B<Definition:> Some nodes have attribute settings. This method returns a hashref with any
827             attribute settings attached as key => value pairs or an empty hash for no attributes
828              
829             B<Accepts:> nothing
830              
831             B<Returns:> { attribute_1 => attribute_1_value ... etc. }
832              
833             =back
834              
835             =head3 advance_element_position( [$node_name], [$number_of_times_to_index] )
836              
837             =over
838              
839             B<Definition:> This method will attempt to advance to $node_name (optional) or the next node
840             if no $node_name is passed. If there is an expectation of multiple nodes of the same name at
841             the same level you can also pass $number_of_times_to_index (optional). This will move through
842             the xml file at the $node_name level the number of times indicated starting with wherever the
843             xml file is already located. Meaning $number_of_times_to_index is a relative index not an
844             absolute index.
845              
846             B<Accepts:> nothing
847              
848             B<Returns:> success or failure for the method call
849              
850             =back
851              
852             =head3 location_status
853              
854             =over
855              
856             B<Definition:> This method gives three usefull location values with one call
857              
858             B<Accepts:> nothing
859              
860             B<Returns:> ( $node_depth (from the top of the file), $node_name, $node_type (xml numerical value for type) );
861              
862             =back
863              
864             =head2 Delegated Methods
865              
866             These are the methods delegated to this class from L<XML::LibXML::Reader>. For more
867             general parsing of subsections of the xml file also see L<Spreadsheet::XLSX::Reader::LibXML>.
868              
869             =head3 copy_current_node
870              
871             =over
872              
873             B<Delegated from:> L<XML::LibXML::Reader/copyCurrentNode (deep)>
874              
875             Returns an XML::LibXML::Node object
876              
877             =back
878              
879             =head1 SUPPORT
880              
881             =over
882              
883             L<github Spreadsheet::XLSX::Reader::LibXML/issues
884             |https://github.com/jandrew/Spreadsheet-XLSX-Reader-LibXML/issues>
885              
886             =back
887              
888             =head1 TODO
889              
890             =over
891              
892             B<1.> Nothing currently
893              
894             =back
895              
896             =head1 AUTHOR
897              
898             =over
899              
900             =item Jed Lund
901              
902             =item jandrew@cpan.org
903              
904             =back
905              
906             =head1 COPYRIGHT
907              
908             This program is free software; you can redistribute
909             it and/or modify it under the same terms as Perl itself.
910              
911             The full text of the license can be found in the
912             LICENSE file included with this module.
913              
914             This software is copyrighted (c) 2014, 2015 by Jed Lund
915              
916             =head1 DEPENDENCIES
917              
918             =over
919              
920             L<XML::LibXML::Reader>
921              
922             =back
923              
924             =head1 SEE ALSO
925              
926             =over
927              
928             L<Spreadsheet::ParseExcel> - Excel 2003 and earlier
929              
930             L<Spreadsheet::XLSX> - 2007+
931              
932             L<Spreadsheet::ParseXLSX> - 2007+
933              
934             L<Log::Shiras|https://github.com/jandrew/Log-Shiras>
935              
936             =over
937              
938             All lines in this package that use Log::Shiras are commented out
939              
940             =back
941              
942             =back
943              
944             =cut
945              
946             #########1#########2 main pod documentation end 5#########6#########7#########8#########9