File Coverage

blib/lib/Treex/PML/Backend/TrXML.pm
Criterion Covered Total %
statement 29 174 16.6
branch 0 50 0.0
condition 0 17 0.0
subroutine 11 30 36.6
pod 0 6 0.0
total 40 277 14.4


line stmt bran cond sub pod time code
1             ## This is a simple XML backend for TEI files -*-cperl-*-
2             ## author: Petr Pajas
3             # $Id: TrXML.pm 3025 2007-04-23 13:55:04Z pajas $ '
4             #############################################################
5              
6             package Treex::PML::Backend::TrXML;
7 1     1   1352 use Treex::PML;
  1         3  
  1         89  
8 1     1   10 use XML::LibXML;
  1         2  
  1         9  
9 1     1   632 use XML::LibXML::SAX;
  1         1358  
  1         34  
10 1     1   9 use Treex::PML::IO qw(close_backend);
  1         2  
  1         45  
11 1     1   6 use strict;
  1         3  
  1         22  
12              
13 1     1   4 use vars qw($VERSION);
  1         2  
  1         42  
14             BEGIN {
15 1     1   1200 $VERSION='2.24'; # version template
16             }
17              
18             sub test {
19 0     0 0   my ($f)=@_;
20 0 0         if (ref($f)) {
21 0   0       return ($f->getline()=~/\s*\<\?xml / &&
22             $f->getline()=~/\]|\/i);
23             } else {
24 0           my $fh = Treex::PML::IO::open_backend($f,"r");
25 0   0       my $test = $fh && test($fh);
26 0           Treex::PML::IO::close_backend($fh);
27 0           return $test;
28             }
29             }
30              
31             sub open_backend {
32 0     0 0   my ($uri,$rw,$encoding)=@_;
33             # discard encoding and pass the rest to the Treex::PML::IO
34 0 0         Treex::PML::IO::open_backend($uri,$rw,($rw eq 'w' ? $encoding : undef));
35             }
36              
37              
38             sub read {
39 0     0 0   my ($input,$target_doc) = @_;
40             #my $handler = XML::SAX::Writer->new();
41            
42 0           my $handler = Treex::PML::Backend::TrXML::SAXHandler->new(TargetDocument => $target_doc);
43 0           my $p = XML::LibXML::SAX->new(Handler => $handler);
44 0 0         if (ref($input)) {
45 0           $p->parse(Source => { ByteStream => $input });
46             } else {
47 0           $p->parse_uri($input);
48             }
49              
50 0           return 1;
51             }
52              
53             sub xml_quote {
54 0     0 0   local $_=$_[0];
55 0           s/&/&/g;
56 0           s/'/'/g;
57 0           s/"/"/g;
58 0           s/>/>/g;
59 0           s/
60 0           return $_;
61             }
62              
63             sub xml_quote_pcdata {
64 0     0 0   local $_=$_[0];
65 0           s/&/&/g;
66 0           s/>/>/g;
67 0           s/
68 0           return $_;
69             }
70              
71             sub write {
72 0     0 0   my ($output, $src_doc) = @_;
73              
74 0 0         die "Require GLOB reference\n" unless ref($output);
75              
76             # xml_decl
77 0           print $output "
78 0 0         if ($src_doc->metaData('xmldecl_version') ne "") {
79 0           print $output " version=\"".$src_doc->metaData('xmldecl_version')."\"";
80             } else {
81 0           print $output " version=\"1.0\"";
82             }
83 0 0         if ($src_doc->encoding() ne "") {
84 0           print $output " encoding=\"".$src_doc->encoding()."\"";
85             }
86 0 0         if ($src_doc->metaData('xmldecl_standalone') ne "") {
87 0           print $output " standalone=\"".$src_doc->metaData('xmldecl_standalone')."\"";
88             }
89 0           print $output "?>\n";
90              
91             print $output ("
92             " \"http://ufal.mff.cuni.cz/~pajas/tred.dtd\" [\n".
93             "
94 0           join("\n",map { " $_ CDATA #IMPLIED" }
95 0           grep { !/^(?:ORD|HIDE|ID)$/ } $src_doc->FS->attributes).
  0            
96             "\">\n]>\n");
97 0           print $output "\n";
98 0           print $output "\n";
99              
100 0           my @meta=grep { !/^xmldecl_/ } $src_doc->listMetaData();
  0            
101 0 0         if (@meta) {
102 0           print $output "\n";
103 0           foreach (@meta) {
104 0           print $output " metaData($_))."\"/>\n";
105             }
106 0           print $output "\n";
107             }
108              
109 0           print $output "\n";
110 0           foreach my $atr (grep { !/^(?:ORD|HIDE|ID)$/ } $src_doc->FS->attributes) {
  0            
111 0           print $output "
112 0 0         if ($src_doc->FS->isList($atr)) {
113 0           print $output " v=\"",xml_quote(join("|",$src_doc->FS->listValues($atr))),"\"";
114             }
115 0           print $output "/>\n";
116             }
117 0           print $output "\n";
118              
119 0           foreach my $tree ($src_doc->trees) {
120 0           my $node=$tree;
121 0           NODE: while ($node) {
122 0           print $output "
123             print $output
124 0           map { " $_=\"".xml_quote($node->{$_})."\"" }
125 0           grep { $node->{$_} ne "" }
126 0           grep { !/^(?:ORD|HIDE|ID)$/ } $src_doc->FS->attributes;
  0            
127 0           print $output ">\n";
128 0 0         if ($node->firstson) {
129 0           $node=$node->firstson;
130 0           next;
131             }
132 0           while ($node) {
133 0           print $output "\n";
134 0 0         if ($node->rbrother) {
135 0           $node=$node->rbrother;
136 0           next NODE;
137             }
138 0           $node=$node->parent;
139             }
140             }
141             }
142 0           print $output "\n";
143             }
144              
145              
146             # SAX TrXML to Treex::PML::Document transducer
147             package Treex::PML::Backend::TrXML::SAXHandler;
148 1     1   9 use strict;
  1         4  
  1         37  
149              
150 1     1   7 use vars qw($VERSION);
  1         2  
  1         57  
151             BEGIN {
152 1     1   31 $VERSION='2.24'; # version template
153             }
154 1     1   7 use Treex::PML;
  1         2  
  1         1085  
155              
156             sub decode {
157 0     0     my ($self, $str)=@_;
158 0           my $enc=$self->{TargetDocument}->encoding();
159 0 0 0       if ($]>=5.008 or $enc eq "") {
160 0           return $str;
161             } else {
162 0           print "encoding: $enc, $str\n";
163 0           eval {
164 0           $str = XML::LibXML::decodeFromUTF8($enc,$str);
165             };
166 0 0         warn $@ if $@;
167 0           return $str;
168             }
169             }
170              
171             sub new {
172 0     0     my ($class, %args) = @_;
173 0           bless \%args, $class;
174             }
175              
176             sub start_document {
177 0     0     my ($self,$hash) = @_;
178 0   0       $self->{TargetDocument} ||= Treex::PML::Factory->createDocument();
179 0   0       $self->{FSAttrs} ||= [];
180             }
181              
182             sub end_document {
183 0     0     my ($self) = @_;
184             my $FS = Treex::PML::Factory->createFSFormat([
185 0           @{$self->{FSAttrs}},
  0            
186             '@N ORD', '@H HIDE', '@K ID'
187             ]);
188 0           $self->{TargetDocument}->changeFS($FS);
189 0           $self->{TargetDocument};
190             }
191              
192             sub xml_decl {
193 0     0     my ($self,$data) = @_;
194 0           my $doc = $self->{TargetDocument};
195 0           $doc->changeEncoding($data->{Encoding});# || 'iso-8859-2');
196 0           $doc->changeMetaData('xmldecl_version' => $data->{Version});
197 0           $doc->changeMetaData('xmldecl_standalone' => $data->{Standalone});
198             }
199              
200       0     sub characters {
201             # nothing to do so far
202             }
203              
204             sub start_element {
205 0     0     my ($self, $hash) = @_;
206 0           my $elem = $hash->{Name};
207 0           my $attr = $hash->{Attributes};
208 0           my $target_doc = $self->{TargetDocument};
209             # my %attr = map { $_->{Name} => $_->{Value} } values %$attr;
210              
211             # $elem eq 'tree' && do { } # nothing to do
212             # $elem eq 'info' && do { } # nothing to do
213 0 0 0       if ($elem eq 'meta') {
    0          
    0          
    0          
    0          
214              
215             $target_doc->changeMetaData($self->decode($attr->{'{}name'}->{Value}) =>
216 0           $self->decode($attr->{'{}content'}->{Value}));
217              
218             } elsif ($elem eq 'types') {
219              
220             # $target_doc->changeMetaData('TrXML types/@full' => $self->decode($attr->{'{}full'}->{Value}))
221             # if (exists($attr->{'{}full'}));
222              
223             } elsif ($elem eq 't') {
224              
225 0           my $atrname = $attr->{'{}n'}->{Value};
226 0 0         my $v = exists($attr->{'{}v'}) ? $self->decode($attr->{'{}v'}->{Value}) : "";
227              
228 0           push @{$self->{FSAttrs}}, '@P '.$atrname;
  0            
229 0 0         push @{$self->{FSAttrs}}, '@L '.$atrname.'|'.$v if ($v ne "");
  0            
230             # d and m not implemented
231             } elsif ($elem eq 'nd') {
232              
233 0           my $parent = $self->{Node};
234 0           my $new;
235 0 0         if ($parent) {
236 0           $self->{Node} = $new = Treex::PML::Factory->createNode();
237             } else {
238 0           undef $parent;
239 0           $self->{Tree} = $self->{TargetDocument}->new_tree($self->{TargetDocument}->lastTreeNo+1);
240 0           $self->{Node} = $new = $self->{Tree};
241             }
242 0           $new->{ORD}=$attr->{'{}n'}->{Value};
243 0           $new->{HIDE}='hide'x$attr->{'{}h'}->{Value};
244 0           $new->{ID}=$self->decode($attr->{'{}id'}->{Value});
245 0           foreach (grep { !/^{}(?:n|h|id)$/ } keys %$attr) {
  0            
246 0           $new->{$self->decode($attr->{$_}->{Name})} = $self->decode($attr->{$_}->{Value});
247             }
248 0 0         $new->paste_on($parent,'ORD') if ($parent);
249             } elsif ($elem eq 'trees' or $elem eq 'info') {
250             # do nothing
251             } else {
252 0           die "Treex::PML::Backend::TrXML: unknown element $elem\n";
253             }
254 0           $self->{attributes}=$attr;
255             }
256              
257             sub end_element {
258 0     0     my ($self,$hash) = @_;
259              
260 0 0         if ($hash->{Name} eq 'nd') {
    0          
261 0           $self->{Node}=$self->{Node}->parent;
262             } elsif ($hash->{Name} eq 'trees') {
263 0           $self->{Node}=undef;
264             }
265             }
266              
267       0     sub entity_reference {
268             }
269              
270             sub start_cdata { # not much use for this
271 0     0     my $self = shift;
272 0           $self->{InCDATA} = 1;
273             }
274              
275             sub end_cdata { # not much use for this
276 0     0     my $self = shift;
277 0           $self->{InCDATA} = 0;
278             }
279              
280             sub comment {
281 0     0     my $self = $_[0];
282 0           my $data = $_[1];
283 0 0         if ($self->{Node}) {
284 0           $self->{Node}->{xml_comment}.='';
285             }
286             }
287              
288             sub doctype_decl { # not use for this, so far
289 0     0     my ($self,$hash) = @_;
290 0           foreach (qw(Name SystemId PublicId Internal)) {
291 0           $self->{"DocType_$_"} = $hash->{$_};
292             }
293             }
294              
295             1;
296             __END__