source: A2P/a2p/A2P/EService/SimpleXML.pm @ 3

Last change on this file since 3 was 3, checked in by guillaume, 17 years ago
  • AUTHORS: Ajout des différents contributeurs
  • COPYING: Ajout de la licence GPL v3
  • a2p: Préparation des sources pour leur publication sous GPL
  • Property svn:keywords set to Id
File size: 4.1 KB
Line 
1#
2# Copyright (c) 2004-2007 - Consultas, PKG.fr
3#
4# This file is part of A2P.
5#
6# A2P is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or
9# (at your option) any later version.
10#
11# A2P is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with A2P; if not, write to the Free Software
18# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19#
20# $Id: SimpleXML.pm 3 2007-10-18 16:20:19Z guillaume $
21#
22
23package A2P::EService::SimpleXML ;
24
25# API to handle XML format
26
27use strict ;
28use XML::LibXML ;
29use A2P::EService::Tools qw( abort ) ;
30
31BEGIN {
32    our $VERSION = sprintf "%s", q$Rev: 836 $ =~ /(\d[0-9.]+)\s+/ ;
33}
34our $VERSION ;
35
36sub new {
37    my $class = shift ;
38
39    my $parser = new XML::LibXML ;
40    abort "Unable to get an XML parser" unless (defined($parser));
41
42    my $self = {
43        PARSER => $parser,
44        NODES  => {}
45    };
46
47    bless $self, $class ;
48
49    # Still a file if called with an argument
50    $self->loadfile($_[0]) if @_ ;
51
52    return $self ;
53}
54
55sub loadfile {
56    my $self = shift ;
57    my $file = shift or abort "No XML file given to load" ;
58
59    abort "Bad XMLfile found" unless -s $file ;
60
61    my $xml = $self->{PARSER}->parse_file( $file );
62    abort "Can't parse '$file' as XML" unless (defined($xml));
63
64    # Keep trace of encoding
65    $self->{ENCODING} = lc( $xml->encoding() || '' );
66
67    my $root = $xml->lastChild ;
68    abort "No XML root found in file" unless (defined($root));
69
70    return $self->{ROOT} = $root ;
71}
72
73sub encoding {
74    my $self = shift ;
75    return defined($self->{ENCODING}) ? $self->{ENCODING} : '' ;
76}
77
78sub root {
79    my $self = shift ;
80    return defined($self->{ROOT}) ? $self->{ROOT} : '' ;
81}
82
83sub name {
84    my $root = $_[0]->root ;
85    return $root ? $root->nodeName : '' ;
86}
87
88sub attribut {
89    my $root = $_[0]->root ;
90    my $name = $_[1] or return '' ;
91    return $root ? $root->getAttribute($name) : '' ;
92}
93
94sub content {
95    my $self = shift ;
96    my $root = $self->root ;
97    my $content = $root ? $root->textContent : '' ;
98
99    # Strip first empty lines due to XML format
100    ( $content ) = $content =~ /^\n*(.*)$/ms if $content ;
101
102    return $content ;
103}
104
105sub nodes {
106    my $self = shift ;
107    my $name = shift or return () ;
108    my $filter = shift || {} ;
109
110    my %attrib = () ;
111    while (@_) {
112        my $attribut = shift ;
113        $attrib{$attribut} = "" ;
114    }
115
116    # Control attribut filter is a hash list
117    $filter = {} unless (ref($filter) =~ /^HASH/i);
118
119    # Use cached nodes if still passed here
120    my @nodes ;
121    if ( exists($self->{NODES}->{$name})
122    and ref($self->{NODES}->{$name}) =~ /^ARRAY/i ) {
123        @nodes = @{$self->{NODES}->{$name}} ;
124
125    } else {
126        my $root ;
127        # Return no node value if root is not available
128        return () unless ( $root = $self->root );
129
130        # Get nodes
131        @nodes = $root->getChildrenByTagName($name);
132
133        # Unbind nodes to skip retreiving their content in the body
134        map { $_->unbindNode } @nodes ;
135
136        # Keep the list in cache
137        $self->{NODES}->{$name} = \@nodes ;
138    }
139
140    my @values = () ;
141    foreach my $node ( @nodes ) {
142        # Check if this node is to return
143        my $filtered = 0 ;
144        foreach my $key (keys(%{$filter})) {
145            $filtered ++ ;
146            my $match = $filter->{$key} ;
147            my $value = $node->getAttribute($key) || "" ;
148            next unless ( $value =~ /^$match$/ );
149            $filtered = 0 ;
150            last ;
151        }
152        next if $filtered ;
153
154        my $found = 0 ;
155        foreach my $attribut (keys(%attrib)) {
156            my $value = $node->getAttribute($attribut) || "" ;
157            next unless ($value);
158            $found ++ ;
159            $attrib{$attribut} = $value ;
160        }
161
162        my $content = $node->textContent || "" ;
163        push @values, $found ? [ $content, \%attrib ] : $content ;
164    }
165
166    return @values ;
167}
168
1691;
Note: See TracBrowser for help on using the repository browser.