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   1448954 use version; our $VERSION = version->declare('v0.38.22');
  5         12  
  5         40  
4              
5 5     5   682 use 5.010;
  5         15  
6 5     5   24 use Moose;
  5         10  
  5         41  
7 5     5   34607 use MooseX::StrictConstructor;
  5         64049  
  5         39  
8 5     5   28313 use MooseX::HasDefaults::RO;
  5         15300  
  5         35  
9 5         52 use Types::Standard qw(
10             Int HasMethods Bool
11             Num Str
12 5     5   34260 );
  5         10  
13 5     5   11299 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 => 'info', 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 => 'info', 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             sub _reader_init{
295             my( $self, $reader ) = @_;
296             ###LogSD my $phone = Log::Shiras::Telephone->new( name_space =>
297             ###LogSD $self->get_all_space . '::XMLReader::_reader_init', );
298             ###LogSD $phone->talk( level => 'debug', message => [
299             ###LogSD "loading any file specific settings", ] );
300            
301             if( $self->_get_unique_bits ){
302             ###LogSD $phone->talk( level => 'debug', message => [
303             ###LogSD "loading any file specific settings - since this is the first open", ] );
304             $self->_need_unique_bits( 0 );
305            
306             # Set basic xml values
307             my $xml_string = '<?xml version="';
308             $self->_next_node;
309             if( $self->_version ){
310             $self->_set_xml_version( $self->_version );
311             $xml_string .= $self->_version . '"';
312             }else{
313             confess "Could not find the version of this xml document!";
314             }
315             if( $self->_encoding ){
316             $self->_set_xml_encoding( $self->_encoding );
317             $xml_string = ' encoding="' . $self->_encoding . '"'
318             }else{
319             $self->_clear_xml_encoding;
320             }
321             $xml_string .= '?>';
322             $self->_set_xml_header( $xml_string );
323            
324             # Set the file unique bits
325             ###LogSD $phone->talk( level => 'debug', message =>[
326             ###LogSD "Check if this type of file has unique settings" ], );
327             if( $self->can( '_load_unique_bits' ) ){
328             ###LogSD $phone->talk( level => 'debug', message =>[ "Loading unique bits" ], );
329             $self->_load_unique_bits;
330             ###LogSD $phone->talk( level => 'debug', message =>[
331             ###LogSD "Finished loading unique bits" ], );
332             }
333             $self->start_the_file_over;
334             }else{
335             ###LogSD $phone->talk( level => 'debug', message =>[
336             ###LogSD "This is not the first time the file has been opened - don't reload settings" ], );
337             }
338             ###LogSD $phone->talk( level => 'debug', message => [ "Finished the file initialization" ], );
339             }
340              
341             sub _build_xml_reader{
342             my( $self, $file_handle ) = @_;
343             ###LogSD my $phone = Log::Shiras::Telephone->new( name_space =>
344             ###LogSD $self->get_all_space . '::XMLReader::_build_xml_reader', );
345             ###LogSD $phone->talk( level => 'debug', message => [
346             ###LogSD "turning a file handle into an xml reader", ] );
347            
348             # Build the reader
349             $file_handle->seek( 0, 0 );
350             my $xml_reader = XML::LibXML::Reader->new( IO => $file_handle );
351             $xml_reader->read;
352             ###LogSD $phone->talk( level => 'debug', message =>[ 'Loading reader:', $xml_reader ], );
353             $self->_set_xml_parser( $xml_reader );
354             ###LogSD $phone->talk( level => 'debug', message => [ "Finished loading XML reader" ], );
355             }
356              
357             sub DEMOLISH{
358             my ( $self ) = @_;
359             ###LogSD my $phone = Log::Shiras::Telephone->new( name_space =>
360             ###LogSD $self->get_all_space . '::XMLReader::DEMOLISH', );
361             ###LogSD $phone->talk( level => 'debug', message => [
362             ###LogSD "clearing the reader for log space:" . $self->get_log_space, ] );
363             if( $self->_get_xml_parser ){
364             #~ print "Disconnecting the sheet file handle from the parser\n";
365             ###LogSD $phone->talk( level => 'debug', message =>[ "Disconnecting the file handle from the xml parser", ] );
366             $self->_close_the_sheet;
367             $self->_clear_xml_parser;
368             }
369             }
370              
371             #########1 Phinish 3#########4#########5#########6#########7#########8#########9
372              
373             no Moose;
374            
375             1;
376              
377             #########1 Documentation 3#########4#########5#########6#########7#########8#########9
378             __END__
379              
380             =head1 NAME
381              
382             Spreadsheet::XLSX::Reader::LibXML::XMLReader - A LibXML::Reader xlsx base class
383              
384             =head1 SYNOPSIS
385              
386             package MyPackage;
387             use MooseX::StrictConstructor;
388             use MooseX::HasDefaults::RO;
389             extends 'Spreadsheet::XLSX::Reader::LibXML::XMLReader';
390            
391             =head1 DESCRIPTION
392              
393             This documentation is written to explain ways to use this module when writing your own excel
394             parser. To use the general package for excel parsing out of the box please review the
395             documentation for L<Workbooks|Spreadsheet::XLSX::Reader::LibXML>,
396             L<Worksheets|Spreadsheet::XLSX::Reader::LibXML::Worksheet>, and
397             L<Cells|Spreadsheet::XLSX::Reader::LibXML::Cell>
398              
399             This module provides a generic way to open an xml file or xml file handle and then extract
400             information using the L<XML::LibXML::Reader> parser. The additional methods and attributes
401             are intended to provide some coalated parsing commands that are specifically useful in turning
402             xml to perl data structures.
403              
404             =head2 Attributes
405              
406             Data passed to new when creating an instance. For modification of these attributes see the
407             listed 'attribute methods'. For general information on attributes see
408             L<Moose::Manual::Attributes>. For ways to manage the instance when opened see the
409             L<Methods|/Methods>.
410            
411             =head3 file
412              
413             =over
414              
415             B<Definition:> This attribute holds the file handle for the file being read. If the full
416             file name and path is passed to the attribute it is coerced to an IO::File file handle.
417              
418             B<Default:> no default - this must be provided to read a file
419              
420             B<Required:> yes
421              
422             B<Range:> any unencrypted xml file name and path or IO::File file handle
423              
424             B<attribute methods> Methods provided to adjust this attribute
425            
426             =over
427              
428             B<set_file>
429              
430             =over
431              
432             B<Definition:> change the file value in the attribute (this will reboot
433             the file instance and lock the file)
434              
435             =back
436              
437             B<get_file>
438              
439             =over
440              
441             B<Definition:> Returns the file handle of the file even if a file name
442             was passed
443              
444             =back
445              
446             B<has_file>
447              
448             =over
449              
450             B<Definition:> this is used to see if the file loaded correctly.
451              
452             =back
453              
454             B<clear_file>
455              
456             =over
457              
458             B<Definition:> this clears (and unlocks) the file handle
459              
460             =back
461              
462             =back
463              
464             L<Delegated Methods>
465              
466             =over
467              
468             B<close>
469              
470             =over
471              
472             closes the file handle
473              
474             =back
475              
476             =back
477              
478             =back
479              
480             =head3 error_inst
481              
482             =over
483              
484             B<Definition:> This attribute holds the L<error handler
485             |Spreadsheet::XLSX::Reader::LibXML::Error>.
486              
487             B<Default:> no default - this must be provided to read a file
488              
489             B<Required:> yes
490              
491             B<Range:> any object instance that can provide the required delegated methods.
492              
493             B<attribute methods> Methods provided to adjust this attribute
494              
495             =over
496              
497             B<_clear_error_inst>
498              
499             =over
500              
501             clear the attribute value
502              
503             =back
504              
505             =back
506              
507             B<_get_error_inst>
508              
509             =over
510              
511             get the attribute value
512              
513             =back
514              
515             =back
516              
517             B<Delegated Methods (required)> Methods delegated to this module by the attribute
518            
519             =over
520              
521             B<error>
522              
523             =over
524              
525             B<Definition:> returns the currently stored error string
526              
527             =back
528              
529             B<set_error>
530              
531             =over
532              
533             B<Definition:> Sets the error string
534              
535             =back
536              
537             B<clear_error>
538              
539             =over
540              
541             B<Definition:> clears the error string
542              
543             =back
544              
545             B<set_warnings>
546              
547             =over
548              
549             B<Definition:> Sets the state that determins if the instance pro-activly
550             warns with the error string when the error string is set.
551              
552             =back
553              
554             B<if_warn>
555              
556             =over
557              
558             B<Definition:> Returns the current state of the state value from 'set_warnings'
559              
560             =back
561              
562             =back
563              
564             =head3 xml_version
565              
566             =over
567              
568             B<Definition:> This stores the xml version stored in the xml header. It is read
569             when the file handle is first set in this sheet.
570              
571             B<Default:> no default - this is auto read from the header
572              
573             B<Required:> no
574              
575             B<Range:> xml versions
576              
577             B<attribute methods> Methods provided to adjust this attribute
578              
579             =over
580              
581             B<_clear_xml_version>
582              
583             =over
584              
585             clear the attribute value
586              
587             =back
588              
589             =back
590              
591             B<_set_xml_version>
592              
593             =over
594              
595             set the attribute value
596              
597             =back
598              
599             =back
600              
601             =head3 xml_encoding
602              
603             =over
604              
605             B<Definition:> This stores the data encoding of the xml file from the xml header.
606             It is read when the file handle is first set in this sheet.
607              
608             B<Default:> no default - this is auto read from the header
609              
610             B<Required:> no
611              
612             B<Range:> valid xml file encoding
613              
614             B<attribute methods> Methods provided to adjust this attribute
615              
616             =over
617              
618             B<encoding>
619              
620             =over
621              
622             get the attribute value
623              
624             =back
625              
626             =back
627              
628             =over
629              
630             B<has_encoding>
631              
632             =over
633              
634             predicate for the attribute value
635              
636             =back
637              
638             =back
639              
640             =over
641              
642             B<_clear_xml_encoding>
643              
644             =over
645              
646             clear the attribute value
647              
648             =back
649              
650             =back
651              
652             B<_set_xml_encoding>
653              
654             =over
655              
656             set the attribute value
657              
658             =back
659              
660             =back
661              
662             =head3 xml_header
663              
664             =over
665              
666             B<Definition:> This stores the xml header from the xml file. It is read when
667             the file handle is first set in this sheet.
668              
669             B<Default:> no default - this is auto read from the header
670              
671             B<Required:> no
672              
673             B<Range:> valid xml file header
674              
675             B<attribute methods> Methods provided to adjust this attribute
676              
677             =over
678              
679             B<get_header>
680              
681             =over
682              
683             get the attribute value
684              
685             =back
686              
687             =back
688              
689             =over
690              
691             B<_set_xml_header>
692              
693             =over
694              
695             set the attribute value
696              
697             =back
698              
699             =back
700              
701             =back
702              
703             =head3 position_index
704              
705             =over
706              
707             B<Definition:> This attribute is available to facilitate other consuming roles and
708             classes. Of the attribute methods only the 'clear_location' method is used in this
709             class during the 'start_the_file_over' method. It can be used for tracking same level
710             positions with the same node name.
711              
712             B<Default:> no default - this is mostly managed by the child class or add on role
713              
714             B<Required:> no
715              
716             B<Range:> Integer
717              
718             B<attribute methods> Methods provided to adjust this attribute
719              
720             =over
721              
722             B<where_am_i>
723              
724             =over
725              
726             get the attribute value
727              
728             =back
729              
730             =back
731              
732             =over
733              
734             B<i_am_here>
735              
736             =over
737              
738             set the attribute value
739              
740             =back
741              
742             =back
743              
744             =over
745              
746             B<clear_location>
747              
748             =over
749              
750             clear the attribute value
751              
752             =back
753              
754             =back
755              
756             =over
757              
758             B<has_position>
759              
760             =over
761              
762             set the attribute value
763              
764             =back
765              
766             =back
767              
768             =back
769              
770             =head2 Methods
771              
772             These are the methods provided by this class. They most likely should be agumented
773             with file specific methods when extending this module.
774              
775             =head3 start_the_file_over
776              
777             =over
778              
779             B<Definition:> This will disconnect the L<XML::LibXML::Reader> from the file handle,
780             rewind the file handle, and then reconnect the L<XML::LibXML::Reader> to the file handle.
781              
782             B<Accepts:> nothing
783              
784             B<Returns:> nothing
785              
786             =back
787              
788             =head3 get_text_node
789              
790             =over
791              
792             B<Definition:> This will collect the text node at the current node position. It will return
793             two items ( $success_or_failure, $text_node_value )
794              
795             B<Accepts:> nothing
796              
797             B<Returns:> ( $success_or_failure(1|undef), ($text_node_value|undef) )
798              
799             =back
800              
801             =head3 get_attribute_hash_ref
802              
803             =over
804              
805             B<Definition:> Some nodes have attribute settings. This method returns a hashref with any
806             attribute settings attached as key => value pairs or an empty hash for no attributes
807              
808             B<Accepts:> nothing
809              
810             B<Returns:> { attribute_1 => attribute_1_value ... etc. }
811              
812             =back
813              
814             =head3 advance_element_position( [$node_name], [$number_of_times_to_index] )
815              
816             =over
817              
818             B<Definition:> This method will attempt to advance to $node_name (optional) or the next node
819             if no $node_name is passed. If there is an expectation of multiple nodes of the same name at
820             the same level you can also pass $number_of_times_to_index (optional). This will move through
821             the xml file at the $node_name level the number of times indicated starting with wherever the
822             xml file is already located. Meaning $number_of_times_to_index is a relative index not an
823             absolute index.
824              
825             B<Accepts:> nothing
826              
827             B<Returns:> success or failure for the method call
828              
829             =back
830              
831             =head3 location_status
832              
833             =over
834              
835             B<Definition:> This method gives three usefull location values with one call
836              
837             B<Accepts:> nothing
838              
839             B<Returns:> ( $node_depth (from the top of the file), $node_name, $node_type (xml numerical value for type) );
840              
841             =back
842              
843             =head2 Delegated Methods
844              
845             These are the methods delegated to this class from L<XML::LibXML::Reader>. For more
846             general parsing of subsections of the xml file also see L<Spreadsheet::XLSX::Reader::LibXML>.
847              
848             =head3 copy_current_node
849              
850             =over
851              
852             B<Delegated from:> L<XML::LibXML::Reader/copyCurrentNode (deep)>
853              
854             Returns an XML::LibXML::Node object
855              
856             =back
857              
858             =head1 SUPPORT
859              
860             =over
861              
862             L<github Spreadsheet::XLSX::Reader::LibXML/issues
863             |https://github.com/jandrew/Spreadsheet-XLSX-Reader-LibXML/issues>
864              
865             =back
866              
867             =head1 TODO
868              
869             =over
870              
871             B<1.> Nothing currently
872              
873             =back
874              
875             =head1 AUTHOR
876              
877             =over
878              
879             =item Jed Lund
880              
881             =item jandrew@cpan.org
882              
883             =back
884              
885             =head1 COPYRIGHT
886              
887             This program is free software; you can redistribute
888             it and/or modify it under the same terms as Perl itself.
889              
890             The full text of the license can be found in the
891             LICENSE file included with this module.
892              
893             This software is copyrighted (c) 2014, 2015 by Jed Lund
894              
895             =head1 DEPENDENCIES
896              
897             =over
898              
899             L<XML::LibXML::Reader>
900              
901             =back
902              
903             =head1 SEE ALSO
904              
905             =over
906              
907             L<Spreadsheet::ParseExcel> - Excel 2003 and earlier
908              
909             L<Spreadsheet::XLSX> - 2007+
910              
911             L<Spreadsheet::ParseXLSX> - 2007+
912              
913             L<Log::Shiras|https://github.com/jandrew/Log-Shiras>
914              
915             =over
916              
917             All lines in this package that use Log::Shiras are commented out
918              
919             =back
920              
921             =back
922              
923             =cut
924              
925             #########1#########2 main pod documentation end 5#########6#########7#########8#########9