line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
## -*- cperl -*- |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
package XML::DT; |
4
|
6
|
|
|
6
|
|
556867
|
use 5.008006; |
|
6
|
|
|
|
|
37
|
|
5
|
|
|
|
|
|
|
|
6
|
6
|
|
|
6
|
|
26
|
use strict; |
|
6
|
|
|
|
|
10
|
|
|
6
|
|
|
|
|
137
|
|
7
|
|
|
|
|
|
|
|
8
|
6
|
|
|
6
|
|
2644
|
use Data::Dumper; |
|
6
|
|
|
|
|
27456
|
|
|
6
|
|
|
|
|
361
|
|
9
|
|
|
|
|
|
|
|
10
|
6
|
|
|
6
|
|
3632
|
use HTTP::Tiny; |
|
6
|
|
|
|
|
232047
|
|
|
6
|
|
|
|
|
300
|
|
11
|
|
|
|
|
|
|
my $ua = HTTP::Tiny->new(); |
12
|
|
|
|
|
|
|
|
13
|
6
|
|
|
6
|
|
2793
|
use XML::DTDParser "ParseDTDFile"; |
|
6
|
|
|
|
|
36037
|
|
|
6
|
|
|
|
|
373
|
|
14
|
|
|
|
|
|
|
|
15
|
6
|
|
|
6
|
|
3401
|
use XML::LibXML ':libxml'; |
|
6
|
|
|
|
|
176048
|
|
|
6
|
|
|
|
|
36
|
|
16
|
|
|
|
|
|
|
our $PARSER = 'XML::LibXML'; |
17
|
|
|
|
|
|
|
|
18
|
6
|
|
|
6
|
|
3064
|
use parent 'Exporter'; |
|
6
|
|
|
|
|
1413
|
|
|
6
|
|
|
|
|
40
|
|
19
|
|
|
|
|
|
|
|
20
|
6
|
|
|
|
|
32871
|
use vars qw($c $u %v $q @dtcontext %dtcontextcount @dtatributes |
21
|
6
|
|
|
6
|
|
346
|
@dtattributes ); |
|
6
|
|
|
|
|
12
|
|
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
our @EXPORT = qw(&dt &dtstring &dturl &inctxt &ctxt &mkdtskel &inpath |
24
|
|
|
|
|
|
|
&mkdtskel_fromDTD &mkdtdskel &tohtml &toxml &MMAPON $c %v $q $u |
25
|
|
|
|
|
|
|
&xmltree &pathdturl @dtcontext %dtcontextcount |
26
|
|
|
|
|
|
|
@dtatributes @dtattributes &pathdt &pathdtstring |
27
|
|
|
|
|
|
|
&father &gfather &ggfather &root); |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
our $VERSION = '0.69'; |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
=encoding utf-8 |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
=head1 NAME |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
XML::DT - a package for down translation of XML files |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
=head1 SYNOPSIS |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
use XML::DT; |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
%xml=( 'music' => sub{"Music from: $c\n"}, |
42
|
|
|
|
|
|
|
'lyrics' => sub{"Lyrics from: $v{name}\n"}, |
43
|
|
|
|
|
|
|
'title' => sub{ uc($c) }, |
44
|
|
|
|
|
|
|
'-userdata => { something => 'I like' }, |
45
|
|
|
|
|
|
|
'-default' => sub{"$q:$c"} ); |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
print dt($filename,%xml); |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
=head1 ABSTRACT |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
This module is a XML down processor. It maps tag (element) |
52
|
|
|
|
|
|
|
names to functions to process that element and respective |
53
|
|
|
|
|
|
|
contents. |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
=head1 DESCRIPTION |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
This module processes XML files with an approach similar to |
58
|
|
|
|
|
|
|
OMNIMARK. As XML parser it uses XML::LibXML module in an independent |
59
|
|
|
|
|
|
|
way. |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
You can parse HTML files as if they were XML files. For this, you must |
62
|
|
|
|
|
|
|
supply an extra option to the hash: |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
%hander = ( -html => 1, |
65
|
|
|
|
|
|
|
... |
66
|
|
|
|
|
|
|
); |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
You can also ask the parser to recover from XML errors: |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
%hander = ( -recover => 1, |
71
|
|
|
|
|
|
|
... |
72
|
|
|
|
|
|
|
); |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
=head1 Functions |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
=head2 dt |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
Down translation function C receives a filename and a set of |
79
|
|
|
|
|
|
|
expressions (functions) defining the processing and associated values |
80
|
|
|
|
|
|
|
for each element. |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
=head2 dtstring |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
C works in a similar way with C but takes input from a |
85
|
|
|
|
|
|
|
string instead of a file. |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
=head2 dturl |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
C works in a similar way with C but takes input from an |
90
|
|
|
|
|
|
|
Internet url instead of a file. |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
=head2 pathdt |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
The C function is a C function which can handle a subset |
95
|
|
|
|
|
|
|
of XPath on handler keys. Example: |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
%handler = ( |
98
|
|
|
|
|
|
|
"article/title" => sub{ toxml("h1",{},$c) }, |
99
|
|
|
|
|
|
|
"section/title" => sub{ toxml("h2",{},$c) }, |
100
|
|
|
|
|
|
|
"title" => sub{ $c }, |
101
|
|
|
|
|
|
|
"//image[@type='jpg']" => sub{ "JPEG: " }, |
102
|
|
|
|
|
|
|
"//image[@type='bmp']" => sub{ "BMP: sorry, no bitmaps on the web" }, |
103
|
|
|
|
|
|
|
); |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
pathdt($filename, %handler); |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
Here are some examples of valid XPath expressions under XML::DT: |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
/aaa |
110
|
|
|
|
|
|
|
/aaa/bbb |
111
|
|
|
|
|
|
|
//ccc - ccc somewhere (same as "ccc") |
112
|
|
|
|
|
|
|
/*/aaa/* |
113
|
|
|
|
|
|
|
//* - same as "-default" |
114
|
|
|
|
|
|
|
/aaa[@id] - aaa with an attribute id |
115
|
|
|
|
|
|
|
/*[@*] - root with an attribute |
116
|
|
|
|
|
|
|
/aaa[not(@name)] - aaa with no attribute "name" |
117
|
|
|
|
|
|
|
//bbb[@name='foo'] - ... attribute "name" = "foo" |
118
|
|
|
|
|
|
|
/ccc[normalize-space(@name)='bbb'] |
119
|
|
|
|
|
|
|
//*[name()='bbb'] - complex way of saying "//bbb" |
120
|
|
|
|
|
|
|
//*[starts-with(name(),'aa')] - an element named "aa.*" |
121
|
|
|
|
|
|
|
//*[contains(name(),'c')] - an element ".*c.*" |
122
|
|
|
|
|
|
|
//aaa[string-length(name())=4] "...." |
123
|
|
|
|
|
|
|
//aaa[string-length(name())<4] ".{1,4}" |
124
|
|
|
|
|
|
|
//aaa[string-length(name())>5] ".{5,}" |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
Note that not all XPath is currently handled by XML::DT. A lot of |
127
|
|
|
|
|
|
|
XPath will never be added to XML::DT because is not in accordance with |
128
|
|
|
|
|
|
|
the down translation model. For more documentation about XPath check |
129
|
|
|
|
|
|
|
the specification at http://www.w3c.org or some tutorials under |
130
|
|
|
|
|
|
|
http://www.zvon.org |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
=head2 pathdtstring |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
Like the C function but supporting XPath. |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
=head2 pathdturl |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
Like the C function but supporting XPath. |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
=head2 ctxt |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
Returns the context element of the currently being processed |
144
|
|
|
|
|
|
|
element. So, if you call C you will get your father element, |
145
|
|
|
|
|
|
|
and so on. |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
=head2 inpath |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
C is true if the actual element path matches the |
150
|
|
|
|
|
|
|
provided pattern. This function is meant to be used in the element |
151
|
|
|
|
|
|
|
functions in order to achieve context dependent processing. |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
=head2 inctxt |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
C is true if the actual element father matches the |
156
|
|
|
|
|
|
|
provided pattern. |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
=head2 toxml |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
This is the default "-default" function. It can be used to generate |
161
|
|
|
|
|
|
|
XML based on C<$c> C<$q> and C<%v> variables. Example: add a new |
162
|
|
|
|
|
|
|
attribute to element C without changing it: |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
%handler=( ... |
165
|
|
|
|
|
|
|
ele1 => sub { $v{at1} = "v1"; toxml(); }, |
166
|
|
|
|
|
|
|
) |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
C can also be used with 3 arguments: tag, attributes and contents |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
toxml("a",{href=> "http://local/f.html"}, "example") |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
returns: |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
example |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
Empty tags are written as empty tags. If you want an empty tag with opening and |
177
|
|
|
|
|
|
|
closing tags, then use the C. |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
=head2 tohtml |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
See C. |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
=head2 xmltree |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
This simple function just makes a HASH reference: |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
{ -c => $c, -q => $q, all_the_other_attributes } |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
The function C understands this structure and makes XML with it. |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
=head2 mkdtskel |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
Used by the mkdtskel script to generate automatically a XML::DT perl |
194
|
|
|
|
|
|
|
script file based on an XML file. Check C manpage for |
195
|
|
|
|
|
|
|
details. |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
=head2 mkdtskel_fromDTD |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
Used by the mkdtskel script to generate automatically a XML::DT perl |
200
|
|
|
|
|
|
|
script file based on an DTD file. Check C manpage for |
201
|
|
|
|
|
|
|
details. |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
=head2 mkdtdskel |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
Used by the mkdtskel script to generate automatically a XML::DT perl |
206
|
|
|
|
|
|
|
script file based on a DTD file. Check C manpage for |
207
|
|
|
|
|
|
|
details. |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
=head1 Accessing parents |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
With XML::DT you can access an element parent (or grand-parent) |
212
|
|
|
|
|
|
|
attributes, till the root of the XML document. |
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
If you use c<$dtattributes[1]{foo} = 'bar'> on a processing function, |
215
|
|
|
|
|
|
|
you are defining the attribute C for that element parent. |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
In the same way, you can use C<$dtattributes[2]> to access the |
218
|
|
|
|
|
|
|
grand-parent. C<$dtattributes[-1]> is, as expected, the XML document |
219
|
|
|
|
|
|
|
root element. |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
There are some shortcuts: |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
=over 4 |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
=item C |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
=item C |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
=item C |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
You can use these functions to access to your C, grand-father |
232
|
|
|
|
|
|
|
(C) or great-grand-father (C): |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
father("x"); # returns value for attribute "x" on father element |
235
|
|
|
|
|
|
|
father("x", "value"); # sets value for attribute "x" on father |
236
|
|
|
|
|
|
|
# element |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
You can also use it directly as a reference to C<@dtattributes>: |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
father->{"x"}; # gets the attribute |
241
|
|
|
|
|
|
|
father->{"x"} = "value"; # sets the attribute |
242
|
|
|
|
|
|
|
$attributes = father; # gets all attributes reference |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
=item C |
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
You can use it as a function to access to your tree root element. |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
root("x"); # gets attribute C on root element |
250
|
|
|
|
|
|
|
root("x", "value"); # sets value for attribute C on root |
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
You can also use it directly as a reference to C<$dtattributes[-1]>: |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
root->{"x"}; # gets the attribute x |
255
|
|
|
|
|
|
|
root->{"x"} = "value"; # sets the attribute x |
256
|
|
|
|
|
|
|
$attributes = root; # gets all attributes reference |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
=back |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
=head1 User provided element processing functions |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
The user must provide an HASH with a function for each element, that |
263
|
|
|
|
|
|
|
computes element output. Functions can use the element name C<$q>, the |
264
|
|
|
|
|
|
|
element content C<$c> and the attribute values hash C<%v>. |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
All those global variables are defined in C<$CALLER::>. |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
Each time an element is find the associated function is called. |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
Content is calculated by concatenation of element contents strings and |
271
|
|
|
|
|
|
|
interior elements return values. |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
=head2 C<-default> function |
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
When a element has no associated function, the function associated |
276
|
|
|
|
|
|
|
with C<-default> called. If no C<-default> function is defined the |
277
|
|
|
|
|
|
|
default function returns a XML like string for the element. |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
When you use C-type> definitions, you often need do set C<-default> |
280
|
|
|
|
|
|
|
function to return just the contents: C. |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
=head2 C<-outputenc> option |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
C<-outputenc> defines the output encoding (default is Unicode UTF8). |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
=head2 C<-inputenc> option |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
C<-inputenc> forces a input encoding type. Whenever that is possible, |
289
|
|
|
|
|
|
|
define the input encoding in the XML file: |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
=head2 C<-pcdata> function |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
C<-pcdata> function is used to define transformation over the |
296
|
|
|
|
|
|
|
contents. Typically this function should look at context (see |
297
|
|
|
|
|
|
|
C function) |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
The default C<-pcdata> function is the identity |
300
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
=head2 C<-cdata> function |
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
You can process C<> in a way different from pcdata. If you |
304
|
|
|
|
|
|
|
define a C<-cdata> method, it will be used. Otherwise, the C<-pcdata> |
305
|
|
|
|
|
|
|
method is called. |
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
=head2 C<-begin> function |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
Function to be executed before processing XML file. |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
Example of use: initialization of side-effect variables |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
=head2 C<-end> function |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
Function to be executed after processing XML file. I can use C<$c> |
316
|
|
|
|
|
|
|
content value. The value returned by C<-end> will be the C return |
317
|
|
|
|
|
|
|
value. |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
Example of use: post-processing of returned contents |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
=head2 C<-recover> option |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
If set, the parser will try to recover in XML errors. |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
=head2 C<-html> option |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
If set, the parser will try to recover in errors. Note that this |
328
|
|
|
|
|
|
|
differs from the previous one in the sense it uses some knowledge of |
329
|
|
|
|
|
|
|
the HTML structure for the recovery. |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
=head2 C<-userdata> option |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
Use this to pass any information you like to your handlers. The data |
334
|
|
|
|
|
|
|
structure you pass in this option will be available as C<< $u >> in |
335
|
|
|
|
|
|
|
your code. -- New in 0.62. |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
=head1 Elements with values other than strings (C<-type>) |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
By default all elements return strings, and contents (C<$c>) is the |
341
|
|
|
|
|
|
|
concatenation of the strings returned by the sub-elements. |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
In some situations the XML text contains values that are better |
344
|
|
|
|
|
|
|
processed as a structured type. |
345
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
The following types (functors) are available: |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
=over 4 |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
=item THE_CHILD |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
Return the result of processing the only child of the element. |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
=item LAST_CHILD |
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
Returns the result of processing the last child of the element. |
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
=item STR |
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
concatenates all the sub-elements returned values (DEFAULT) all the |
361
|
|
|
|
|
|
|
sub-element should return strings to be concatenated; |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
=item SEQ |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
makes an ARRAY with all the sub elements contents; attributes are |
366
|
|
|
|
|
|
|
ignored (they should be processed in the sub-element). (returns a ref) |
367
|
|
|
|
|
|
|
If you have different types of sub-elements, you should use SEQH |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
=item SEQH |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
makes an ARRAY of HASH with all the sub elements (returns a ref); for |
372
|
|
|
|
|
|
|
each sub-element: |
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
-q => element name |
375
|
|
|
|
|
|
|
-c => contents |
376
|
|
|
|
|
|
|
at1 => at value1 for each attribute |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
=item MAP |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
makes an HASH with the sub elements; keys are the sub-element names, |
381
|
|
|
|
|
|
|
values are their contents. Attributes are ignored. (they should be |
382
|
|
|
|
|
|
|
processed in the sub-element) (returns a ref) |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
=item MULTIMAP |
385
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
makes an HASH of ARRAY; keys are the sub-element names; values are |
387
|
|
|
|
|
|
|
lists of contents; attributes are ignored (they should be processed in |
388
|
|
|
|
|
|
|
the sub-element); (returns a ref) |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
=item MMAPON(element-list) |
391
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
makes an HASH with the sub-elements; keys are the sub-element names, |
393
|
|
|
|
|
|
|
values are their contents; attributes are ignored (they should be |
394
|
|
|
|
|
|
|
processed in the sub-element); for all the elements contained in the |
395
|
|
|
|
|
|
|
element-list, it is created an ARRAY with their contents. (returns a |
396
|
|
|
|
|
|
|
ref) |
397
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
=item XML |
399
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
return a reference to an HASH with: |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
-q => element name |
403
|
|
|
|
|
|
|
-c => contents |
404
|
|
|
|
|
|
|
at1 => at value1 for each attribute |
405
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
=item ZERO |
407
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
don't process the sub-elements; return "" |
409
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
=back |
411
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
When you use C-type> definitions, you often need do set C<-default> |
413
|
|
|
|
|
|
|
function returning just the contents C. |
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
=head2 An example: |
416
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
use XML::DT; |
418
|
|
|
|
|
|
|
%handler = ( contacts => sub{ [ split(";",$c)] }, |
419
|
|
|
|
|
|
|
-default => sub{$c}, |
420
|
|
|
|
|
|
|
-type => { institution => 'MAP', |
421
|
|
|
|
|
|
|
degrees => MMAPON('name') |
422
|
|
|
|
|
|
|
tels => 'SEQ' } |
423
|
|
|
|
|
|
|
); |
424
|
|
|
|
|
|
|
$a = dt ("f.xml", %handler); |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
with the following f.xml |
427
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
U.M. |
431
|
|
|
|
|
|
|
University of Minho |
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
- 1111
|
434
|
|
|
|
|
|
|
- 1112
|
435
|
|
|
|
|
|
|
- 1113
|
436
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
Portugal |
438
|
|
|
|
|
|
|
J.Joao; J.Rocha; J.Ramalho |
439
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
Computer science |
441
|
|
|
|
|
|
|
Informatica |
442
|
|
|
|
|
|
|
history |
443
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
would make $a |
446
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
{ 'name' => [ 'Computer science', |
448
|
|
|
|
|
|
|
'Informatica ', |
449
|
|
|
|
|
|
|
' history ' ], |
450
|
|
|
|
|
|
|
'institution' => { 'tels' => [ 1111, 1112, 1113 ], |
451
|
|
|
|
|
|
|
'name' => 'University of Minho', |
452
|
|
|
|
|
|
|
'where' => 'Portugal', |
453
|
|
|
|
|
|
|
'id' => 'U.M.', |
454
|
|
|
|
|
|
|
'contacts' => [ 'J.Joao', |
455
|
|
|
|
|
|
|
' J.Rocha', |
456
|
|
|
|
|
|
|
' J.Ramalho' ] } }; |
457
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
=head1 DT Skeleton generation |
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
It is possible to build an initial processor program based on an example |
462
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
To do this use the function C. |
464
|
|
|
|
|
|
|
|
465
|
|
|
|
|
|
|
Example: |
466
|
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
perl -MXML::DT -e 'mkdtskel "f.xml"' > f.pl |
468
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
=head1 DTD skeleton generation |
470
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
It makes a naive DTD based on an example(s). |
472
|
|
|
|
|
|
|
|
473
|
|
|
|
|
|
|
To do this use the function C. |
474
|
|
|
|
|
|
|
|
475
|
|
|
|
|
|
|
Example: |
476
|
|
|
|
|
|
|
|
477
|
|
|
|
|
|
|
perl -MXML::DT -e 'mkdtdskel "f.xml"' > f.dtd |
478
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
=head1 SEE ALSO |
480
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
mkdtskel(1) and mkdtdskel(1) |
482
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
=head1 AUTHORS |
484
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
Home for XML::DT; |
486
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
http://natura.di.uminho.pt/~jj/perl/XML/ |
488
|
|
|
|
|
|
|
|
489
|
|
|
|
|
|
|
Jose Joao Almeida, |
490
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
Alberto Manuel Simões, |
492
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
=head1 ACKNOWLEDGEMENTS |
494
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
Michel Rodriguez |
496
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
José Carlos Ramalho |
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
Mark A. Hillebrand |
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
502
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
Copyright 1999-2012 Project Natura. |
504
|
|
|
|
|
|
|
|
505
|
|
|
|
|
|
|
This library is free software; you can redistribute it |
506
|
|
|
|
|
|
|
and/or modify it under the same terms as Perl itself. |
507
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
=cut |
509
|
|
|
|
|
|
|
|
510
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
our %ty = (); |
513
|
|
|
|
|
|
|
|
514
|
|
|
|
|
|
|
sub dt { |
515
|
13
|
|
|
13
|
1
|
5975
|
my ($file, %xml)=@_; |
516
|
13
|
|
|
|
|
17
|
my ($parser, $tree); |
517
|
|
|
|
|
|
|
|
518
|
|
|
|
|
|
|
# Treat -decl option |
519
|
13
|
|
|
|
|
21
|
my $declr = ""; |
520
|
13
|
50
|
|
|
|
32
|
if ($xml{-declr}) { |
521
|
0
|
0
|
|
|
|
0
|
if ($xml{-outputenc}) { |
522
|
0
|
|
|
|
|
0
|
$declr = "\n"; |
523
|
|
|
|
|
|
|
} else { |
524
|
0
|
|
|
|
|
0
|
$declr = "\n"; |
525
|
|
|
|
|
|
|
} |
526
|
|
|
|
|
|
|
} |
527
|
|
|
|
|
|
|
|
528
|
13
|
|
|
|
|
22
|
%ty = (); |
529
|
13
|
50
|
|
|
|
27
|
%ty = (%{$xml{'-type'}}) if defined($xml{'-type'}); |
|
0
|
|
|
|
|
0
|
|
530
|
13
|
|
|
|
|
38
|
$ty{-ROOT} = "NONE"; |
531
|
|
|
|
|
|
|
|
532
|
13
|
50
|
|
|
|
30
|
&{$xml{-begin}} if $xml{-begin}; |
|
0
|
|
|
|
|
0
|
|
533
|
|
|
|
|
|
|
|
534
|
|
|
|
|
|
|
# TODO --- how to force encoding with XML::LibXML? |
535
|
|
|
|
|
|
|
# $xml{-inputenc} |
536
|
|
|
|
|
|
|
|
537
|
|
|
|
|
|
|
# create a new LibXML parser |
538
|
13
|
|
|
|
|
51
|
$parser = XML::LibXML->new(); |
539
|
|
|
|
|
|
|
|
540
|
|
|
|
|
|
|
#### We don't wan't DT to load everytime the DTD (I Think!) |
541
|
13
|
|
|
|
|
205
|
$parser->validation(0); |
542
|
|
|
|
|
|
|
# $parser->expand_xinclude(0); # testing |
543
|
13
|
|
|
|
|
169
|
$parser->load_ext_dtd(0); |
544
|
13
|
|
|
|
|
129
|
$parser->expand_entities(0); |
545
|
13
|
50
|
|
|
|
133
|
$parser->expand_xincludes(1) if $xml{'-xinclude'}; |
546
|
|
|
|
|
|
|
|
547
|
|
|
|
|
|
|
# parse the file |
548
|
13
|
|
|
|
|
16
|
my $doc; |
549
|
13
|
50
|
|
|
|
33
|
if ( $xml{'-recover'}) { |
|
|
50
|
|
|
|
|
|
550
|
0
|
|
|
|
|
0
|
$parser->recover(1); |
551
|
0
|
|
|
|
|
0
|
eval { |
552
|
0
|
|
|
0
|
|
0
|
local $SIG{__WARN__} = sub{}; |
553
|
0
|
|
|
|
|
0
|
$doc = $parser->parse_file($file); |
554
|
|
|
|
|
|
|
}; |
555
|
0
|
0
|
|
|
|
0
|
return undef if !$doc; |
556
|
|
|
|
|
|
|
} |
557
|
|
|
|
|
|
|
elsif ( $xml{'-html'}) { |
558
|
0
|
|
|
|
|
0
|
$parser->recover(1); |
559
|
0
|
|
|
|
|
0
|
eval { |
560
|
0
|
|
|
0
|
|
0
|
local $SIG{__WARN__} = sub{}; |
561
|
0
|
|
|
|
|
0
|
$doc = $parser->parse_html_file($file); |
562
|
|
|
|
|
|
|
}; |
563
|
0
|
0
|
|
|
|
0
|
return undef if !$doc; |
564
|
|
|
|
|
|
|
} |
565
|
|
|
|
|
|
|
else { |
566
|
13
|
|
|
|
|
33
|
$doc = $parser->parse_file($file) |
567
|
|
|
|
|
|
|
} |
568
|
|
|
|
|
|
|
|
569
|
|
|
|
|
|
|
# get the document root element |
570
|
13
|
|
|
|
|
3148
|
$tree = $doc->getDocumentElement(); |
571
|
|
|
|
|
|
|
|
572
|
13
|
|
|
|
|
25
|
my $return = ""; |
573
|
|
|
|
|
|
|
# execute End action if it exists |
574
|
13
|
100
|
|
|
|
30
|
if($xml{-end}) { |
575
|
1
|
|
|
|
|
6
|
$c = _omni("-ROOT", \%xml, $tree); |
576
|
1
|
|
|
|
|
2
|
$return = &{$xml{-end}} |
|
1
|
|
|
|
|
2
|
|
577
|
|
|
|
|
|
|
} else { |
578
|
12
|
|
|
|
|
29
|
$return = _omni("-ROOT",\%xml, $tree) |
579
|
|
|
|
|
|
|
} |
580
|
|
|
|
|
|
|
|
581
|
13
|
50
|
|
|
|
24
|
if ($declr) { |
582
|
0
|
|
|
|
|
0
|
return $declr.$return; |
583
|
|
|
|
|
|
|
} else { |
584
|
13
|
|
|
|
|
47
|
return $return; |
585
|
|
|
|
|
|
|
} |
586
|
|
|
|
|
|
|
} |
587
|
|
|
|
|
|
|
|
588
|
|
|
|
|
|
|
|
589
|
|
|
|
|
|
|
sub ctxt { |
590
|
0
|
|
|
0
|
1
|
0
|
my $level = $_[0]; |
591
|
0
|
|
|
|
|
0
|
$dtcontext[-$level-1]; |
592
|
|
|
|
|
|
|
} |
593
|
|
|
|
|
|
|
|
594
|
|
|
|
|
|
|
sub inpath { |
595
|
0
|
|
|
0
|
1
|
0
|
my $pattern = shift ; |
596
|
0
|
|
|
|
|
0
|
join ("/", @dtcontext) =~ m!\b$pattern\b!; |
597
|
|
|
|
|
|
|
} |
598
|
|
|
|
|
|
|
|
599
|
|
|
|
|
|
|
|
600
|
|
|
|
|
|
|
sub inctxt { |
601
|
38
|
|
|
38
|
1
|
39
|
my $pattern = shift ; |
602
|
|
|
|
|
|
|
# see if is in root context... |
603
|
38
|
100
|
100
|
|
|
136
|
return 1 if (($pattern eq "^" && @dtcontext==1) || $pattern eq ".*"); |
|
|
|
100
|
|
|
|
|
604
|
11
|
|
|
|
|
108
|
join("/", @dtcontext) =~ m!$pattern/[^/]*$! ; |
605
|
|
|
|
|
|
|
} |
606
|
|
|
|
|
|
|
|
607
|
|
|
|
|
|
|
sub father { |
608
|
0
|
|
|
0
|
1
|
0
|
my ($a,$b)=@_; |
609
|
0
|
0
|
|
|
|
0
|
if (defined($b)){$dtattributes[1]{$a} = $b} |
|
0
|
0
|
|
|
|
0
|
|
610
|
0
|
|
|
|
|
0
|
elsif(defined($a)){$dtattributes[1]{$a} } |
611
|
0
|
|
|
|
|
0
|
else {$dtattributes[1]} |
612
|
|
|
|
|
|
|
} |
613
|
|
|
|
|
|
|
|
614
|
|
|
|
|
|
|
sub gfather { |
615
|
0
|
|
|
0
|
1
|
0
|
my ($a,$b)=@_; |
616
|
0
|
0
|
|
|
|
0
|
if (defined($b)){$dtattributes[2]{$a} = $b} |
|
0
|
0
|
|
|
|
0
|
|
617
|
0
|
|
|
|
|
0
|
elsif(defined($a)){$dtattributes[2]{$a} } |
618
|
0
|
|
|
|
|
0
|
else {$dtattributes[2]} |
619
|
|
|
|
|
|
|
} |
620
|
|
|
|
|
|
|
|
621
|
|
|
|
|
|
|
|
622
|
|
|
|
|
|
|
sub ggfather { |
623
|
0
|
|
|
0
|
1
|
0
|
my ($a,$b)=@_; |
624
|
0
|
0
|
|
|
|
0
|
if (defined($b)){$dtattributes[3]{$a} = $b} |
|
0
|
0
|
|
|
|
0
|
|
625
|
0
|
|
|
|
|
0
|
elsif(defined($a)){$dtattributes[3]{$a} } |
626
|
0
|
|
|
|
|
0
|
else {$dtattributes[3]} |
627
|
|
|
|
|
|
|
} |
628
|
|
|
|
|
|
|
|
629
|
|
|
|
|
|
|
|
630
|
|
|
|
|
|
|
sub root { ### the root |
631
|
0
|
|
|
0
|
1
|
0
|
my ($a,$b)=@_; |
632
|
0
|
0
|
|
|
|
0
|
if (defined($b)){$dtattributes[-1]{$a} = $b } |
|
0
|
0
|
|
|
|
0
|
|
633
|
0
|
|
|
|
|
0
|
elsif(defined($a)){$dtattributes[-1]{$a} } |
634
|
0
|
|
|
|
|
0
|
else {$dtattributes[-1] } |
635
|
|
|
|
|
|
|
} |
636
|
|
|
|
|
|
|
|
637
|
|
|
|
|
|
|
sub pathdtstring{ |
638
|
12
|
|
|
12
|
1
|
5874
|
my $string = shift; |
639
|
12
|
|
|
|
|
26
|
my %h = _pathtodt(@_); |
640
|
12
|
|
|
|
|
29
|
return dtstring($string,%h); |
641
|
|
|
|
|
|
|
} |
642
|
|
|
|
|
|
|
|
643
|
|
|
|
|
|
|
|
644
|
|
|
|
|
|
|
|
645
|
|
|
|
|
|
|
sub pathdturl{ |
646
|
0
|
|
|
0
|
1
|
0
|
my $url = shift; |
647
|
0
|
|
|
|
|
0
|
my %h = _pathtodt(@_); |
648
|
0
|
|
|
|
|
0
|
return dturl($url,%h); |
649
|
|
|
|
|
|
|
} |
650
|
|
|
|
|
|
|
|
651
|
|
|
|
|
|
|
|
652
|
|
|
|
|
|
|
|
653
|
|
|
|
|
|
|
sub dturl{ |
654
|
0
|
|
|
0
|
1
|
0
|
my $url = shift; |
655
|
0
|
|
|
|
|
0
|
my $contents = $ua->get($url); |
656
|
0
|
0
|
|
|
|
0
|
if ($contents->{success}) { |
657
|
|
|
|
|
|
|
# warn("JJ ok\n"); |
658
|
0
|
|
|
|
|
0
|
return dtstring($contents->{content}, @_); |
659
|
|
|
|
|
|
|
} else { |
660
|
|
|
|
|
|
|
# warn("JJ not ok\n"); |
661
|
0
|
|
|
|
|
0
|
warn("$contents->{status}: $contents->{reason}"); |
662
|
0
|
|
|
|
|
0
|
return undef; |
663
|
|
|
|
|
|
|
} |
664
|
|
|
|
|
|
|
} |
665
|
|
|
|
|
|
|
|
666
|
|
|
|
|
|
|
|
667
|
|
|
|
|
|
|
|
668
|
|
|
|
|
|
|
sub dtstring { |
669
|
20
|
|
|
20
|
1
|
4233
|
my ($string, %xml)=@_; |
670
|
20
|
|
|
|
|
27
|
my ($parser, $tree); |
671
|
|
|
|
|
|
|
|
672
|
20
|
|
|
|
|
25
|
my $declr = ""; |
673
|
20
|
100
|
|
|
|
47
|
if ($xml{-declr}) { |
674
|
1
|
50
|
|
|
|
3
|
if ($xml{-outputenc}) { |
675
|
0
|
|
|
|
|
0
|
$declr = "\n"; |
676
|
|
|
|
|
|
|
} else { |
677
|
1
|
|
|
|
|
2
|
$declr = "\n"; |
678
|
|
|
|
|
|
|
} |
679
|
|
|
|
|
|
|
} |
680
|
|
|
|
|
|
|
|
681
|
20
|
100
|
|
|
|
46
|
$xml{'-type'} = {} unless defined $xml{'-type'}; |
682
|
20
|
|
|
|
|
22
|
%ty = (%{$xml{'-type'}}, -ROOT => "NONE"); |
|
20
|
|
|
|
|
74
|
|
683
|
|
|
|
|
|
|
|
684
|
|
|
|
|
|
|
# execute Begin action if it exists |
685
|
20
|
50
|
|
|
|
41
|
if ($xml{-begin}) { |
686
|
0
|
|
|
|
|
0
|
&{$xml{-begin}} |
|
0
|
|
|
|
|
0
|
|
687
|
|
|
|
|
|
|
} |
688
|
|
|
|
|
|
|
|
689
|
20
|
100
|
|
|
|
36
|
if ($xml{-inputenc}) { |
690
|
3
|
|
|
|
|
30
|
$string = XML::LibXML::encodeToUTF8($xml{-inputenc}, $string); |
691
|
|
|
|
|
|
|
} |
692
|
|
|
|
|
|
|
|
693
|
|
|
|
|
|
|
# create a new LibXML parser |
694
|
20
|
|
|
|
|
64
|
$parser = XML::LibXML->new(); |
695
|
20
|
|
|
|
|
255
|
$parser->validation(0); |
696
|
20
|
|
|
|
|
234
|
$parser->load_ext_dtd(0); |
697
|
20
|
|
|
|
|
186
|
$parser->expand_entities(0); |
698
|
|
|
|
|
|
|
|
699
|
|
|
|
|
|
|
# parse the string |
700
|
20
|
|
|
|
|
187
|
my $doc; |
701
|
20
|
50
|
|
|
|
48
|
if ( $xml{'-recover'}) { |
|
|
50
|
|
|
|
|
|
702
|
0
|
|
|
|
|
0
|
$parser->recover(1); |
703
|
0
|
|
|
|
|
0
|
eval { |
704
|
0
|
|
|
0
|
|
0
|
local $SIG{__WARN__} = sub{}; |
705
|
0
|
|
|
|
|
0
|
$doc = $parser->parse_string($string); |
706
|
|
|
|
|
|
|
}; |
707
|
0
|
0
|
|
|
|
0
|
return undef if !$doc; |
708
|
|
|
|
|
|
|
} |
709
|
|
|
|
|
|
|
elsif ( $xml{'-html'}) { |
710
|
0
|
|
|
|
|
0
|
$parser->recover(1); |
711
|
0
|
|
|
|
|
0
|
eval{ |
712
|
0
|
|
|
0
|
|
0
|
local $SIG{__WARN__} = sub{}; |
713
|
0
|
|
|
|
|
0
|
$doc = $parser->parse_html_string($string); |
714
|
|
|
|
|
|
|
}; |
715
|
|
|
|
|
|
|
# if ($@) { return undef; } |
716
|
0
|
0
|
|
|
|
0
|
return undef unless defined $doc; |
717
|
|
|
|
|
|
|
} else { |
718
|
20
|
|
|
|
|
45
|
$doc = $parser->parse_string($string); |
719
|
|
|
|
|
|
|
} |
720
|
|
|
|
|
|
|
|
721
|
|
|
|
|
|
|
# get the document root element |
722
|
20
|
|
|
|
|
2864
|
$tree = $doc->getDocumentElement(); |
723
|
|
|
|
|
|
|
|
724
|
20
|
|
|
|
|
27
|
my $return; |
725
|
|
|
|
|
|
|
|
726
|
|
|
|
|
|
|
# Check if we have an end function |
727
|
20
|
50
|
|
|
|
40
|
if ($xml{-end}) { |
728
|
0
|
|
|
|
|
0
|
$c = _omni("-ROOT", \%xml, $tree); |
729
|
0
|
|
|
|
|
0
|
$return = &{$xml{-end}} |
|
0
|
|
|
|
|
0
|
|
730
|
|
|
|
|
|
|
} else { |
731
|
20
|
|
|
|
|
47
|
$return = _omni("-ROOT", \%xml, $tree) |
732
|
|
|
|
|
|
|
} |
733
|
|
|
|
|
|
|
|
734
|
20
|
100
|
|
|
|
44
|
if ($declr) { |
735
|
1
|
|
|
|
|
6
|
return $declr.$return; |
736
|
|
|
|
|
|
|
} else { |
737
|
19
|
|
|
|
|
67
|
return $return; |
738
|
|
|
|
|
|
|
} |
739
|
|
|
|
|
|
|
} |
740
|
|
|
|
|
|
|
|
741
|
|
|
|
|
|
|
|
742
|
|
|
|
|
|
|
|
743
|
|
|
|
|
|
|
sub pathdt{ |
744
|
0
|
|
|
0
|
1
|
0
|
my $file = shift; |
745
|
0
|
|
|
|
|
0
|
my %h = _pathtodt(@_); |
746
|
0
|
|
|
|
|
0
|
return dt($file,%h); |
747
|
|
|
|
|
|
|
} |
748
|
|
|
|
|
|
|
|
749
|
|
|
|
|
|
|
|
750
|
|
|
|
|
|
|
|
751
|
|
|
|
|
|
|
# Parsing dos predicados do XPath |
752
|
|
|
|
|
|
|
sub _testAttr { |
753
|
9
|
|
|
9
|
|
15
|
my $atr = shift; |
754
|
9
|
|
|
|
|
18
|
for ($atr) { |
755
|
9
|
|
|
|
|
13
|
s/name\(\)/'$q'/g; |
756
|
|
|
|
|
|
|
# s/\@([A-Za-z_]+)/'$v{$1}'/g; |
757
|
9
|
50
|
|
|
|
31
|
s/\@([A-Za-z_]+)/defined $v{$1}?"'$v{$1}'":"''"/ge; |
|
4
|
|
|
|
|
19
|
|
758
|
9
|
100
|
|
|
|
22
|
s/\@\*/keys %v?"'1'":"''"/ge; |
|
5
|
|
|
|
|
14
|
|
759
|
9
|
50
|
|
|
|
68
|
if (/^not\((.*)\)$/) { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
760
|
0
|
|
|
|
|
0
|
return ! _testAttr($1); |
761
|
|
|
|
|
|
|
} elsif (/^('|")([^\1]*)(\1)\s*=\s*('|")([^\4]*)\4$/) { |
762
|
4
|
|
|
|
|
19
|
return ($2 eq $5); |
763
|
|
|
|
|
|
|
} elsif (/^(.*?)normalize-space\((['"])([^\2)]*)\2\)(.*)$/) { |
764
|
0
|
|
|
|
|
0
|
my ($back,$forward)=($1,$4); |
765
|
0
|
|
|
|
|
0
|
my $x = _normalize_space($3); |
766
|
0
|
|
|
|
|
0
|
return _testAttr("$back'$x'$forward"); |
767
|
|
|
|
|
|
|
} elsif (/starts-with\((['"])([^\1))]*)\1,(['"])([^\3))]*)\3\)/) { |
768
|
0
|
|
|
|
|
0
|
my $x = _starts_with($2,$4); |
769
|
0
|
|
|
|
|
0
|
return $x; |
770
|
|
|
|
|
|
|
} elsif (/contains\((['"])([^\1))]*)\1,(['"])([^\3))]*)\3\)/) { |
771
|
0
|
|
|
|
|
0
|
my $x = _contains($2,$4); |
772
|
0
|
|
|
|
|
0
|
return $x; |
773
|
|
|
|
|
|
|
} elsif (/^(.*?)string-length\((['"])([^\2]*)\2\)(.*)$/) { |
774
|
0
|
|
|
|
|
0
|
my ($back,$forward) = ($1,$4); |
775
|
0
|
|
|
|
|
0
|
my $x = length($3); |
776
|
0
|
|
|
|
|
0
|
return _testAttr("$back$x$forward"); |
777
|
|
|
|
|
|
|
} elsif (/^(\d+)\s*=(\d+)$/) { |
778
|
0
|
|
|
|
|
0
|
return ($1 == $2); |
779
|
|
|
|
|
|
|
} elsif (/^(\d+)\s*<(\d+)$/) { |
780
|
0
|
|
|
|
|
0
|
return ($1 < $2); |
781
|
|
|
|
|
|
|
} elsif (/^(\d+)\s*>(\d+)$/) { |
782
|
0
|
|
|
|
|
0
|
return ($1 > $2); |
783
|
|
|
|
|
|
|
} elsif (/^(['"])([^\1]*)\1$/) { |
784
|
5
|
|
|
|
|
20
|
return $2; |
785
|
|
|
|
|
|
|
} |
786
|
|
|
|
|
|
|
} |
787
|
0
|
|
|
|
|
0
|
return 0; #$atr; |
788
|
|
|
|
|
|
|
} |
789
|
|
|
|
|
|
|
|
790
|
|
|
|
|
|
|
|
791
|
|
|
|
|
|
|
|
792
|
|
|
|
|
|
|
# Funcao auxiliar de teste de predicados do XPath |
793
|
|
|
|
|
|
|
sub _starts_with { |
794
|
0
|
|
|
0
|
|
0
|
my ($string,$preffix) = @_; |
795
|
0
|
0
|
0
|
|
|
0
|
return 0 unless ($string && $preffix); |
796
|
0
|
0
|
|
|
|
0
|
return 1 if ($string =~ m!^$preffix!); |
797
|
0
|
|
|
|
|
0
|
return 0; |
798
|
|
|
|
|
|
|
} |
799
|
|
|
|
|
|
|
|
800
|
|
|
|
|
|
|
|
801
|
|
|
|
|
|
|
# Funcao auxiliar de teste de predicados do XPath |
802
|
|
|
|
|
|
|
sub _contains { |
803
|
0
|
|
|
0
|
|
0
|
my ($string,$s) = @_; |
804
|
0
|
0
|
0
|
|
|
0
|
return 0 unless ($string && $s); |
805
|
0
|
0
|
|
|
|
0
|
return 1 if ($string =~ m!$s!); |
806
|
0
|
|
|
|
|
0
|
return 0; |
807
|
|
|
|
|
|
|
} |
808
|
|
|
|
|
|
|
|
809
|
|
|
|
|
|
|
|
810
|
|
|
|
|
|
|
# Funcao auxiliar de teste de predicados do XPath |
811
|
|
|
|
|
|
|
sub _normalize_space { |
812
|
4
|
|
|
4
|
|
116
|
my $z = shift; |
813
|
4
|
|
|
|
|
22
|
$z =~ /^\s*(.*?)\s*$/; |
814
|
4
|
|
|
|
|
9
|
$z = $1; |
815
|
4
|
|
|
|
|
11
|
$z =~ s!\s+! !g; |
816
|
4
|
|
|
|
|
18
|
return $z; |
817
|
|
|
|
|
|
|
} |
818
|
|
|
|
|
|
|
|
819
|
|
|
|
|
|
|
|
820
|
|
|
|
|
|
|
sub _pathtodt { |
821
|
12
|
|
|
12
|
|
32
|
my %h = @_; |
822
|
12
|
|
|
|
|
19
|
my %aux=(); |
823
|
12
|
|
|
|
|
13
|
my %aux2=(); |
824
|
12
|
|
|
|
|
14
|
my %n = (); |
825
|
12
|
|
|
|
|
22
|
my $z; |
826
|
12
|
|
|
|
|
35
|
for $z (keys %h) { |
827
|
|
|
|
|
|
|
# TODO - Make it more generic |
828
|
16
|
100
|
|
|
|
94
|
if ( $z=~m{\w+(\|\w+)+}) { |
|
|
100
|
|
|
|
|
|
829
|
1
|
|
|
|
|
3
|
my @tags = split /\|/, $z; |
830
|
1
|
|
|
|
|
3
|
for(@tags) { |
831
|
3
|
|
|
|
|
6
|
$aux2{$_}=$h{$z} |
832
|
|
|
|
|
|
|
} |
833
|
|
|
|
|
|
|
} |
834
|
|
|
|
|
|
|
elsif ( $z=~m{(//|/|)(.*)/([^\[]*)(?:\[(.*)\])?} ) { |
835
|
10
|
|
|
|
|
35
|
my ($first,$second,$third,$fourth) = ($1,$2,$3,$4); |
836
|
10
|
100
|
100
|
|
|
34
|
if (($first eq "/") && (!$second)) { |
837
|
7
|
|
|
|
|
11
|
$first = ""; |
838
|
7
|
|
|
|
|
7
|
$second = '.*'; |
839
|
7
|
|
|
|
|
16
|
$third =~ s!\*!-default!; |
840
|
|
|
|
|
|
|
} else { |
841
|
3
|
|
|
|
|
6
|
$second =~ s!\*!\[^/\]\+!g; |
842
|
3
|
|
|
|
|
4
|
$second =~ s!/$!\(/\.\*\)\?!g; |
843
|
3
|
|
|
|
|
4
|
$second =~ s!//!\(/\.\*\)\?/!g; |
844
|
3
|
|
|
|
|
6
|
$third =~ s!\*!-default!g; |
845
|
|
|
|
|
|
|
} |
846
|
10
|
|
|
|
|
12
|
push( @{$aux{$third}} , [$first,$second,$h{$z},$fourth]); |
|
10
|
|
|
|
|
39
|
|
847
|
|
|
|
|
|
|
} |
848
|
5
|
|
|
|
|
7
|
else { $aux2{$z}=$h{$z};} |
849
|
|
|
|
|
|
|
} |
850
|
12
|
|
|
|
|
23
|
for $z (keys %aux){ |
851
|
|
|
|
|
|
|
my $code = sub { |
852
|
38
|
|
|
38
|
|
37
|
my $l; |
853
|
38
|
|
|
|
|
38
|
for $l (@{$aux{$z}}) { |
|
38
|
|
|
|
|
55
|
|
854
|
38
|
|
|
|
|
42
|
my $prefix = ""; |
855
|
38
|
100
|
100
|
|
|
100
|
$prefix = "^" unless (($l->[0]) or ($l->[1])); |
856
|
38
|
50
|
66
|
|
|
61
|
$prefix = "^" if (($l->[0] eq "/") && ($l->[1])); |
857
|
38
|
100
|
|
|
|
50
|
if ($l->[3]) { |
858
|
9
|
100
|
66
|
|
|
28
|
if(inctxt("$prefix$l->[1]") && _testAttr($l->[3])) |
859
|
4
|
|
|
|
|
7
|
{return &{$l->[2]}; } |
|
4
|
|
|
|
|
9
|
|
860
|
|
|
|
|
|
|
} else { |
861
|
29
|
100
|
|
|
|
54
|
if(inctxt("$prefix$l->[1]")) {return &{$l->[2]};} |
|
20
|
|
|
|
|
22
|
|
|
20
|
|
|
|
|
34
|
|
862
|
|
|
|
|
|
|
} |
863
|
|
|
|
|
|
|
} |
864
|
14
|
50
|
|
|
|
26
|
return &{ $aux2{$z}} if $aux2{$z} ; |
|
0
|
|
|
|
|
0
|
|
865
|
14
|
100
|
|
|
|
22
|
return &{ $h{-default}} if $h{-default}; |
|
4
|
|
|
|
|
7
|
|
866
|
10
|
|
|
|
|
16
|
&toxml(); |
867
|
10
|
|
|
|
|
37
|
}; |
868
|
10
|
|
|
|
|
20
|
$n{$z} = $code; |
869
|
|
|
|
|
|
|
} |
870
|
12
|
|
|
|
|
19
|
for $z (keys %aux2){ |
871
|
8
|
|
33
|
|
|
26
|
$n{$z} ||= $aux2{$z} ; |
872
|
|
|
|
|
|
|
} |
873
|
12
|
|
|
|
|
37
|
return %n; |
874
|
|
|
|
|
|
|
} |
875
|
|
|
|
|
|
|
|
876
|
|
|
|
|
|
|
|
877
|
|
|
|
|
|
|
|
878
|
|
|
|
|
|
|
sub _omni { |
879
|
242
|
|
|
242
|
|
419
|
my ($par, $xml, @l) = @_; |
880
|
|
|
|
|
|
|
my $defaulttype = |
881
|
|
|
|
|
|
|
(exists($xml->{-type}) && exists($xml->{-type}{-default})) |
882
|
|
|
|
|
|
|
? |
883
|
242
|
100
|
100
|
|
|
625
|
$xml->{-type}{-default} : "STR"; |
884
|
242
|
|
66
|
|
|
568
|
my $type = $ty{$par} || $defaulttype; |
885
|
242
|
|
|
|
|
266
|
my %typeargs = (); |
886
|
|
|
|
|
|
|
|
887
|
242
|
50
|
|
|
|
364
|
if (ref($type) eq "mmapon") { |
888
|
0
|
|
|
|
|
0
|
$typeargs{$_} = 1 for (@$type); |
889
|
0
|
|
|
|
|
0
|
$type = "MMAPON"; |
890
|
|
|
|
|
|
|
} |
891
|
|
|
|
|
|
|
|
892
|
242
|
|
|
|
|
230
|
my $r ; |
893
|
242
|
100
|
33
|
|
|
642
|
if( $type eq 'STR') { $r = "" } |
|
202
|
50
|
66
|
|
|
203
|
|
|
|
100
|
66
|
|
|
|
|
|
|
100
|
33
|
|
|
|
|
|
|
50
|
33
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
894
|
0
|
|
|
|
|
0
|
elsif( $type eq 'THE_CHILD' or $type eq 'LAST_CHILD') { $r = 0 } |
895
|
5
|
|
|
|
|
9
|
elsif( $type eq 'SEQ' or $type eq "ARRAY") { $r = [] } |
896
|
2
|
|
|
|
|
2
|
elsif( $type eq 'SEQH' or $type eq "ARRAYOFHASH") { $r = [] } |
897
|
0
|
|
|
|
|
0
|
elsif( $type eq 'MAP' or $type eq "HASH") { $r = {} } |
898
|
0
|
|
|
|
|
0
|
elsif( $type eq 'MULTIMAP') { $r = {} } |
899
|
0
|
|
|
|
|
0
|
elsif( $type eq 'MMAPON' or $type eq "HASHOFARRAY") { $r = {} } |
900
|
33
|
|
|
|
|
42
|
elsif( $type eq 'NONE') { $r = "" } |
901
|
0
|
|
|
|
|
0
|
elsif( $type eq 'ZERO') { return "" } |
902
|
|
|
|
|
|
|
|
903
|
242
|
|
|
|
|
256
|
my ($name, $val, @val, $atr, $aux); |
904
|
|
|
|
|
|
|
|
905
|
242
|
|
|
|
|
262
|
$u = $xml->{-userdata}; |
906
|
242
|
|
|
|
|
342
|
while(@l) { |
907
|
507
|
|
|
|
|
562
|
my $tree = shift @l; |
908
|
507
|
50
|
|
|
|
1262
|
next unless $tree; |
909
|
|
|
|
|
|
|
|
910
|
507
|
50
|
|
|
|
2763
|
$name = ref($tree) eq "XML::LibXML::CDATASection" ? "-pcdata" : $tree->getName(); |
911
|
|
|
|
|
|
|
|
912
|
507
|
50
|
|
|
|
1157
|
if (ref($tree) eq "XML::LibXML::CDATASection") { |
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
913
|
0
|
|
|
|
|
0
|
$val = $tree->getData(); |
914
|
|
|
|
|
|
|
|
915
|
0
|
|
|
|
|
0
|
$name = "-cdata"; |
916
|
0
|
0
|
|
|
|
0
|
$aux = (defined($xml->{-outputenc}))?_fromUTF8($val,$xml->{-outputenc}):$val; |
917
|
|
|
|
|
|
|
|
918
|
0
|
0
|
|
|
|
0
|
if (defined($xml->{-cdata})) { |
|
|
0
|
|
|
|
|
|
919
|
0
|
|
|
|
|
0
|
push(@dtcontext,"-cdata"); |
920
|
0
|
|
|
|
|
0
|
$c = $aux; |
921
|
0
|
|
|
|
|
0
|
$aux = &{$xml->{-cdata}}; |
|
0
|
|
|
|
|
0
|
|
922
|
0
|
|
|
|
|
0
|
pop(@dtcontext); |
923
|
|
|
|
|
|
|
} elsif (defined($xml->{-pcdata})) { |
924
|
0
|
|
|
|
|
0
|
push(@dtcontext,"-pcdata"); |
925
|
0
|
|
|
|
|
0
|
$c = $aux; |
926
|
0
|
|
|
|
|
0
|
$aux = &{$xml->{-pcdata}}; |
|
0
|
|
|
|
|
0
|
|
927
|
0
|
|
|
|
|
0
|
pop(@dtcontext); |
928
|
|
|
|
|
|
|
} |
929
|
|
|
|
|
|
|
|
930
|
|
|
|
|
|
|
} elsif (ref($tree) eq "XML::LibXML::Comment") { |
931
|
|
|
|
|
|
|
### At the moment, treat as Text |
932
|
|
|
|
|
|
|
### We will need to change this, I hope! |
933
|
0
|
|
|
|
|
0
|
$val = ""; |
934
|
0
|
|
|
|
|
0
|
$name = "-pcdata"; |
935
|
0
|
0
|
|
|
|
0
|
$aux= (defined($xml->{-outputenc}))?_fromUTF8($val, $xml->{-outputenc}):$val; |
936
|
0
|
0
|
|
|
|
0
|
if (defined($xml->{-pcdata})) { |
937
|
0
|
|
|
|
|
0
|
push(@dtcontext,"-pcdata"); |
938
|
0
|
|
|
|
|
0
|
$c = $aux; |
939
|
0
|
|
|
|
|
0
|
$aux = &{$xml->{-pcdata}}; |
|
0
|
|
|
|
|
0
|
|
940
|
0
|
|
|
|
|
0
|
pop(@dtcontext); |
941
|
|
|
|
|
|
|
} |
942
|
|
|
|
|
|
|
} |
943
|
|
|
|
|
|
|
elsif (ref($tree) eq "XML::LibXML::Text") { |
944
|
298
|
|
|
|
|
641
|
$val = $tree->getData(); |
945
|
|
|
|
|
|
|
|
946
|
298
|
|
|
|
|
336
|
$name = "-pcdata"; |
947
|
298
|
100
|
|
|
|
436
|
$aux = (defined($xml->{-outputenc}))?_fromUTF8($val,$xml->{-outputenc}):$val; |
948
|
|
|
|
|
|
|
|
949
|
298
|
50
|
|
|
|
451
|
if (defined($xml->{-pcdata})) { |
950
|
0
|
|
|
|
|
0
|
push(@dtcontext,"-pcdata"); |
951
|
0
|
|
|
|
|
0
|
$c = $aux; |
952
|
0
|
|
|
|
|
0
|
$aux = &{$xml->{-pcdata}}; |
|
0
|
|
|
|
|
0
|
|
953
|
0
|
|
|
|
|
0
|
pop(@dtcontext); |
954
|
|
|
|
|
|
|
} |
955
|
|
|
|
|
|
|
|
956
|
|
|
|
|
|
|
} elsif (ref($tree) eq "XML::LibXML::Element") { |
957
|
209
|
|
|
|
|
293
|
my %atr = _nodeAttributes($tree); |
958
|
209
|
|
|
|
|
294
|
$atr = \%atr; |
959
|
|
|
|
|
|
|
|
960
|
209
|
100
|
|
|
|
330
|
if (exists($xml->{-ignorecase})) { |
961
|
40
|
|
|
|
|
57
|
$name = lc($name); |
962
|
40
|
|
|
|
|
67
|
for (keys %$atr) { |
963
|
8
|
|
|
|
|
19
|
my ($k,$v) = (lc($_),$atr->{$_}); |
964
|
8
|
|
|
|
|
12
|
delete($atr->{$_}); |
965
|
8
|
|
|
|
|
16
|
$atr->{$k} = $v; |
966
|
|
|
|
|
|
|
} |
967
|
|
|
|
|
|
|
} |
968
|
|
|
|
|
|
|
|
969
|
209
|
|
|
|
|
298
|
push(@dtcontext,$name); |
970
|
209
|
|
|
|
|
288
|
$dtcontextcount{$name}++; |
971
|
209
|
|
|
|
|
243
|
unshift(@dtatributes, $atr); |
972
|
209
|
|
|
|
|
205
|
unshift(@dtattributes, $atr); |
973
|
209
|
|
|
|
|
710
|
$aux = _omniele($xml, $name, _omni($name, $xml, ($tree->getChildnodes())), $atr); |
974
|
209
|
|
|
|
|
832
|
shift(@dtatributes); |
975
|
209
|
|
|
|
|
1574
|
shift(@dtattributes); |
976
|
209
|
|
|
|
|
212
|
pop(@dtcontext); $dtcontextcount{$name}--; |
|
209
|
|
|
|
|
314
|
|
977
|
|
|
|
|
|
|
} elsif (ref($tree) eq "XML::LibXML::Node") { |
978
|
0
|
0
|
|
|
|
0
|
if ($tree->nodeType == XML_ENTITY_REF_NODE) { |
979
|
|
|
|
|
|
|
# if we get here, is because we are not expanding entities (I think) |
980
|
0
|
0
|
|
|
|
0
|
if ($tree->textContent) { |
981
|
0
|
|
|
|
|
0
|
$aux = $tree->textContent; |
982
|
|
|
|
|
|
|
} else { |
983
|
0
|
|
|
|
|
0
|
$aux = '&'.$tree->nodeName.';'; |
984
|
|
|
|
|
|
|
} |
985
|
|
|
|
|
|
|
} else { |
986
|
0
|
|
|
|
|
0
|
print STDERR "Not handled, generic node of type: [",$tree->nodeType,"]\n"; |
987
|
|
|
|
|
|
|
} |
988
|
|
|
|
|
|
|
} else { |
989
|
0
|
|
|
|
|
0
|
print STDERR "Not handled: [",ref($tree),"]\n"; |
990
|
|
|
|
|
|
|
} |
991
|
|
|
|
|
|
|
|
992
|
507
|
100
|
33
|
|
|
927
|
if ($type eq "STR"){ if (defined($aux)) {$r .= $aux} ;} |
|
461
|
100
|
66
|
|
|
605
|
|
|
446
|
50
|
66
|
|
|
791
|
|
|
|
100
|
33
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
993
|
|
|
|
|
|
|
elsif ($type eq "THE_CHILD" or $type eq "LAST_CHILD"){ |
994
|
0
|
0
|
|
|
|
0
|
$r = $aux unless _whitepc($aux, $name); } |
995
|
|
|
|
|
|
|
elsif ($type eq "SEQ" or $type eq "ARRAY"){ |
996
|
9
|
50
|
|
|
|
15
|
push(@$r, $aux) unless _whitepc($aux, $name);} |
997
|
|
|
|
|
|
|
elsif ($type eq "SEQH" or $type eq "ARRAYHASH"){ |
998
|
4
|
50
|
|
|
|
7
|
push(@$r,{"-c" => $aux, |
999
|
|
|
|
|
|
|
"-q" => $name, |
1000
|
|
|
|
|
|
|
_nodeAttributes($tree) |
1001
|
|
|
|
|
|
|
}) unless _whitepc($aux,$name); |
1002
|
|
|
|
|
|
|
} |
1003
|
|
|
|
|
|
|
elsif($type eq "MMAPON"){ |
1004
|
0
|
0
|
|
|
|
0
|
if(not _whitepc($aux,$name)){ |
1005
|
0
|
0
|
|
|
|
0
|
if(! $typeargs{$name}) { |
1006
|
0
|
0
|
|
|
|
0
|
warn "duplicated tag '$name'\n" if(defined($r->{$name})); |
1007
|
0
|
|
|
|
|
0
|
$r->{$name} = $aux } |
1008
|
0
|
0
|
|
|
|
0
|
else { push(@{$r->{$name}},$aux) unless _whitepc($aux,$name)}} |
|
0
|
|
|
|
|
0
|
|
1009
|
|
|
|
|
|
|
} |
1010
|
|
|
|
|
|
|
elsif($type eq "MAP" or $type eq "HASH"){ |
1011
|
0
|
0
|
|
|
|
0
|
if(not _whitepc($aux,$name)){ |
1012
|
0
|
0
|
|
|
|
0
|
warn "duplicated tag '$name'\n" if(defined($r->{$name})); |
1013
|
0
|
|
|
|
|
0
|
$r->{$name} = $aux }} |
1014
|
|
|
|
|
|
|
elsif($type eq "MULTIMAP"){ |
1015
|
0
|
0
|
|
|
|
0
|
push(@{$r->{$name}},$aux) unless _whitepc($aux,$name)} |
|
0
|
|
|
|
|
0
|
|
1016
|
33
|
|
|
|
|
100
|
elsif($type eq "NONE"){ $r = $aux;} |
1017
|
0
|
|
|
|
|
0
|
else { $r="undefined type !!!"} |
1018
|
|
|
|
|
|
|
} |
1019
|
242
|
|
|
|
|
551
|
$r; |
1020
|
|
|
|
|
|
|
} |
1021
|
|
|
|
|
|
|
|
1022
|
|
|
|
|
|
|
|
1023
|
|
|
|
|
|
|
|
1024
|
|
|
|
|
|
|
sub _omniele { |
1025
|
209
|
|
|
209
|
|
236
|
my $xml = shift; |
1026
|
209
|
|
|
|
|
201
|
my $aux; |
1027
|
209
|
|
|
|
|
308
|
($q, $c, $aux) = @_; |
1028
|
|
|
|
|
|
|
|
1029
|
209
|
|
|
|
|
354
|
%v = %$aux; |
1030
|
|
|
|
|
|
|
|
1031
|
209
|
100
|
|
|
|
319
|
if (defined($xml->{-outputenc})) { |
1032
|
3
|
|
|
|
|
7
|
for (keys %v){ |
1033
|
|
|
|
|
|
|
$v{$_} = _fromUTF8($v{$_}, $xml->{-outputenc}) |
1034
|
1
|
|
|
|
|
6
|
} |
1035
|
|
|
|
|
|
|
} |
1036
|
|
|
|
|
|
|
|
1037
|
209
|
100
|
|
|
|
390
|
if (defined $xml->{$q}) |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1038
|
53
|
|
|
|
|
54
|
{ &{$xml->{$q}} } |
|
53
|
|
|
|
|
90
|
|
1039
|
|
|
|
|
|
|
elsif (defined $xml->{'-default'}) |
1040
|
149
|
|
|
|
|
144
|
{ &{$xml->{'-default'}} } |
|
149
|
|
|
|
|
227
|
|
1041
|
|
|
|
|
|
|
elsif (defined $xml->{'-tohtml'}) |
1042
|
0
|
|
|
|
|
0
|
{ tohtml() } |
1043
|
|
|
|
|
|
|
else |
1044
|
7
|
|
|
|
|
15
|
{ toxml() } |
1045
|
|
|
|
|
|
|
} |
1046
|
|
|
|
|
|
|
|
1047
|
|
|
|
|
|
|
|
1048
|
|
|
|
|
|
|
|
1049
|
0
|
|
|
0
|
1
|
0
|
sub xmltree { +{'-c' => $c, '-q' => $q, %v} } |
1050
|
|
|
|
|
|
|
|
1051
|
|
|
|
|
|
|
sub tohtml { |
1052
|
44
|
|
|
44
|
1
|
55
|
my ($q,$v,$c); |
1053
|
|
|
|
|
|
|
|
1054
|
44
|
50
|
|
|
|
76
|
if (not @_) { |
|
|
100
|
|
|
|
|
|
1055
|
0
|
|
|
|
|
0
|
($q,$v,$c) = ($XML::DT::q, \%XML::DT::v, $XML::DT::c); |
1056
|
|
|
|
|
|
|
} elsif (ref($_[0])) { |
1057
|
21
|
|
|
|
|
25
|
$c = shift; |
1058
|
|
|
|
|
|
|
} else { |
1059
|
23
|
|
|
|
|
36
|
($q,$v,$c) = @_; |
1060
|
|
|
|
|
|
|
} |
1061
|
|
|
|
|
|
|
|
1062
|
44
|
100
|
66
|
|
|
114
|
if (not ref($c)) { |
|
|
100
|
33
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1063
|
23
|
50
|
100
|
|
|
109
|
if ($q eq "-pcdata") { |
|
|
100
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
1064
|
0
|
|
|
|
|
0
|
return $c |
1065
|
|
|
|
|
|
|
} elsif ($q eq "link" || $q eq "br" || $q eq "hr" || $q eq "img") { |
1066
|
4
|
|
|
|
|
7
|
return _openTag($q,$v) |
1067
|
|
|
|
|
|
|
} else { |
1068
|
19
|
|
|
|
|
26
|
return _openTag($q,$v) . "$c$q>" |
1069
|
|
|
|
|
|
|
} |
1070
|
|
|
|
|
|
|
} |
1071
|
|
|
|
|
|
|
elsif (ref($c) eq "HASH" && $c->{'-q'} && $c->{'-c'}) { |
1072
|
16
|
|
|
|
|
38
|
my %a = %$c; |
1073
|
16
|
|
|
|
|
32
|
my ($q,$c) = delete @a{"-q","-c"}; |
1074
|
16
|
100
|
|
|
|
57
|
tohtml($q,\%a,(ref($c)?tohtml($c):$c)); |
1075
|
|
|
|
|
|
|
} |
1076
|
|
|
|
|
|
|
elsif (ref($c) eq "HASH") { |
1077
|
|
|
|
|
|
|
_openTag($q,$v). |
1078
|
|
|
|
|
|
|
join("",map {($_ ne "-pcdata") |
1079
|
|
|
|
|
|
|
? ( (ref($c->{$_}) eq "ARRAY") |
1080
|
|
|
|
|
|
|
? "<$_>". |
1081
|
0
|
|
|
|
|
0
|
join("$_>\n<$_>", @{$c->{$_}}). |
1082
|
|
|
|
|
|
|
"$_>\n" |
1083
|
0
|
0
|
|
|
|
0
|
: tohtml($_,{},$c->{$_})."\n" ) |
|
|
0
|
|
|
|
|
|
1084
|
|
|
|
|
|
|
: () } |
1085
|
0
|
|
|
|
|
0
|
keys %{$c} ) . |
|
0
|
|
|
|
|
0
|
|
1086
|
|
|
|
|
|
|
"$c->{-pcdata}$q>" } ######## "NOTYetREady" |
1087
|
|
|
|
|
|
|
elsif (ref($c) eq "ARRAY") { |
1088
|
5
|
50
|
33
|
|
|
14
|
if (defined($q) && exists($ty{$q}) && $ty{$q} eq "SEQH") { |
|
|
50
|
0
|
|
|
|
|
1089
|
0
|
|
|
|
|
0
|
tohtml($q,$v,join("\n",map {tohtml($_)} @$c)) |
|
0
|
|
|
|
|
0
|
|
1090
|
|
|
|
|
|
|
} elsif (defined $q) { |
1091
|
0
|
|
|
|
|
0
|
tohtml($q,$v,join("",@{$c})) |
|
0
|
|
|
|
|
0
|
|
1092
|
|
|
|
|
|
|
} else { |
1093
|
5
|
50
|
|
|
|
10
|
join("\n",map {(ref($_)?tohtml($_):$_)} @$c) |
|
8
|
|
|
|
|
14
|
|
1094
|
|
|
|
|
|
|
} |
1095
|
|
|
|
|
|
|
} |
1096
|
|
|
|
|
|
|
} |
1097
|
|
|
|
|
|
|
|
1098
|
|
|
|
|
|
|
sub toxml { |
1099
|
118
|
|
|
118
|
1
|
207
|
my ($q,$v,$c); |
1100
|
|
|
|
|
|
|
|
1101
|
118
|
100
|
|
|
|
196
|
if (not @_) { |
|
|
100
|
|
|
|
|
|
1102
|
64
|
|
|
|
|
106
|
($q, $v, $c) = ($XML::DT::q, \%XML::DT::v, $XML::DT::c); |
1103
|
|
|
|
|
|
|
} elsif (ref($_[0])) { |
1104
|
27
|
|
|
|
|
32
|
$c = shift; |
1105
|
|
|
|
|
|
|
} else { |
1106
|
27
|
|
|
|
|
45
|
($q, $v, $c) = @_; |
1107
|
|
|
|
|
|
|
} |
1108
|
|
|
|
|
|
|
|
1109
|
118
|
100
|
66
|
|
|
309
|
if (not ref($c)) { |
|
|
100
|
33
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1110
|
91
|
100
|
|
|
|
154
|
if ($q eq "-pcdata") { |
|
|
100
|
|
|
|
|
|
1111
|
3
|
|
|
|
|
31
|
return $c |
1112
|
|
|
|
|
|
|
} elsif ($c eq "") { |
1113
|
3
|
|
|
|
|
19
|
return _emptyTag($q,$v) |
1114
|
|
|
|
|
|
|
} else { |
1115
|
85
|
|
|
|
|
126
|
return _openTag($q,$v) . "$c$q>" |
1116
|
|
|
|
|
|
|
} |
1117
|
|
|
|
|
|
|
} |
1118
|
|
|
|
|
|
|
elsif (ref($c) eq "HASH" && $c->{'-q'} && $c->{'-c'}) { |
1119
|
20
|
|
|
|
|
61
|
my %a = %$c; |
1120
|
20
|
|
|
|
|
45
|
my ($q,$c) = delete @a{"-q","-c"}; |
1121
|
|
|
|
|
|
|
### _openTag($q,\%a).toxml($c).). |
1122
|
|
|
|
|
|
|
### toxml($q,\%a,join("\n",map {toxml($_)} @$c)) |
1123
|
20
|
100
|
|
|
|
123
|
toxml($q,\%a,(ref($c)?toxml($c):$c)); |
1124
|
|
|
|
|
|
|
} |
1125
|
|
|
|
|
|
|
elsif (ref($c) eq "HASH") { |
1126
|
|
|
|
|
|
|
_openTag($q,$v). |
1127
|
|
|
|
|
|
|
join("",map {($_ ne "-pcdata") |
1128
|
|
|
|
|
|
|
? ( (ref($c->{$_}) eq "ARRAY") |
1129
|
|
|
|
|
|
|
? "<$_>". |
1130
|
0
|
|
|
|
|
0
|
join("$_>\n<$_>", @{$c->{$_}}). |
1131
|
|
|
|
|
|
|
"$_>\n" |
1132
|
0
|
0
|
|
|
|
0
|
: toxml($_,{},$c->{$_})."\n" ) |
|
|
0
|
|
|
|
|
|
1133
|
|
|
|
|
|
|
: () } |
1134
|
0
|
|
|
|
|
0
|
keys %{$c} ) . |
|
0
|
|
|
|
|
0
|
|
1135
|
|
|
|
|
|
|
"$c->{-pcdata}$q>" } ######## "NOTYetREady" |
1136
|
|
|
|
|
|
|
elsif (ref($c) eq "ARRAY") { |
1137
|
7
|
50
|
33
|
|
|
26
|
if (defined($q) && exists($ty{$q}) && $ty{$q} eq "SEQH") { |
|
|
50
|
0
|
|
|
|
|
1138
|
0
|
|
|
|
|
0
|
toxml($q,$v,join("\n",map {toxml($_)} @$c)) |
|
0
|
|
|
|
|
0
|
|
1139
|
|
|
|
|
|
|
} elsif (defined $q) { |
1140
|
0
|
|
|
|
|
0
|
toxml($q,$v,join("",@{$c})) |
|
0
|
|
|
|
|
0
|
|
1141
|
|
|
|
|
|
|
} else { |
1142
|
7
|
50
|
|
|
|
14
|
join("\n",map {(ref($_)?toxml($_):$_)} @$c) |
|
12
|
|
|
|
|
31
|
|
1143
|
|
|
|
|
|
|
} |
1144
|
|
|
|
|
|
|
} |
1145
|
|
|
|
|
|
|
} |
1146
|
|
|
|
|
|
|
|
1147
|
|
|
|
|
|
|
|
1148
|
|
|
|
|
|
|
sub _openTag{ |
1149
|
108
|
|
|
108
|
|
145
|
"<$_[0]". join("",map {" $_=\"$_[1]{$_}\""} keys %{$_[1]} ).">" |
|
13
|
|
|
|
|
88
|
|
|
108
|
|
|
|
|
493
|
|
1150
|
|
|
|
|
|
|
} |
1151
|
|
|
|
|
|
|
|
1152
|
|
|
|
|
|
|
sub _emptyTag{ |
1153
|
3
|
|
|
3
|
|
6
|
"<$_[0]". join("",map {" $_=\"$_[1]{$_}\""} keys %{$_[1]} )."/>" |
|
0
|
|
|
|
|
0
|
|
|
3
|
|
|
|
|
21
|
|
1154
|
|
|
|
|
|
|
} |
1155
|
|
|
|
|
|
|
|
1156
|
|
|
|
|
|
|
|
1157
|
|
|
|
|
|
|
sub mkdtskel_fromDTD { |
1158
|
1
|
|
|
1
|
1
|
832
|
my $filename = shift; |
1159
|
1
|
|
|
|
|
7
|
my $file = ParseDTDFile($filename); |
1160
|
|
|
|
|
|
|
|
1161
|
1
|
|
|
|
|
5573
|
print <<'PERL'; |
1162
|
|
|
|
|
|
|
#!/usr/bin/perl |
1163
|
|
|
|
|
|
|
use warnings; |
1164
|
|
|
|
|
|
|
use strict; |
1165
|
|
|
|
|
|
|
use XML::DT; |
1166
|
|
|
|
|
|
|
my $filename = shift; |
1167
|
|
|
|
|
|
|
|
1168
|
|
|
|
|
|
|
# Variable Reference |
1169
|
|
|
|
|
|
|
# |
1170
|
|
|
|
|
|
|
# $c - contents after child processing |
1171
|
|
|
|
|
|
|
# $q - element name (tag) |
1172
|
|
|
|
|
|
|
# %v - hash of attributes |
1173
|
|
|
|
|
|
|
|
1174
|
|
|
|
|
|
|
my %handler=( |
1175
|
|
|
|
|
|
|
# '-outputenc' => 'ISO-8859-1', |
1176
|
|
|
|
|
|
|
# '-default' => sub{"<$q>$c$q>"}, |
1177
|
|
|
|
|
|
|
PERL |
1178
|
|
|
|
|
|
|
|
1179
|
|
|
|
|
|
|
|
1180
|
1
|
|
|
|
|
9
|
for (sort keys %{$file}) { |
|
1
|
|
|
|
|
11
|
|
1181
|
3
|
|
|
|
|
12
|
print " '$_' => sub { },"; |
1182
|
|
|
|
|
|
|
print " # attributes: ", |
1183
|
3
|
100
|
|
|
|
13
|
join(", ", keys %{$file->{$_}{attributes}}) if exists($file->{$_}{attributes}); |
|
2
|
|
|
|
|
12
|
|
1184
|
3
|
|
|
|
|
12
|
print "\n"; |
1185
|
|
|
|
|
|
|
} |
1186
|
|
|
|
|
|
|
|
1187
|
|
|
|
|
|
|
|
1188
|
1
|
|
|
|
|
20
|
print <<'PERL'; |
1189
|
|
|
|
|
|
|
); |
1190
|
|
|
|
|
|
|
|
1191
|
|
|
|
|
|
|
print dt($filename, %handler); |
1192
|
|
|
|
|
|
|
PERL |
1193
|
|
|
|
|
|
|
|
1194
|
|
|
|
|
|
|
} |
1195
|
|
|
|
|
|
|
|
1196
|
|
|
|
|
|
|
sub mkdtskel{ |
1197
|
1
|
|
|
1
|
1
|
230
|
my @files = @_; |
1198
|
1
|
|
|
|
|
3
|
my $name; |
1199
|
1
|
|
|
|
|
3
|
my $HTML = ""; |
1200
|
1
|
|
|
|
|
2
|
my %element; |
1201
|
|
|
|
|
|
|
my %att; |
1202
|
|
|
|
|
|
|
my %mkdtskel = |
1203
|
|
|
|
|
|
|
('-default' => sub{ |
1204
|
10
|
|
|
10
|
|
16
|
$element{$q}++; |
1205
|
10
|
|
|
|
|
15
|
for (keys %v) { |
1206
|
2
|
|
|
|
|
5
|
$att{$q}{$_} = 1 |
1207
|
|
|
|
|
|
|
}; |
1208
|
10
|
|
|
|
|
20
|
""}, |
1209
|
|
|
|
|
|
|
|
1210
|
|
|
|
|
|
|
'-end' => sub{ |
1211
|
1
|
|
|
1
|
|
12
|
print <<'END'; |
1212
|
|
|
|
|
|
|
#!/usr/bin/perl |
1213
|
|
|
|
|
|
|
use XML::DT; |
1214
|
|
|
|
|
|
|
use warnings; |
1215
|
|
|
|
|
|
|
use strict; |
1216
|
|
|
|
|
|
|
my $filename = shift; |
1217
|
|
|
|
|
|
|
|
1218
|
|
|
|
|
|
|
# Variable Reference |
1219
|
|
|
|
|
|
|
# |
1220
|
|
|
|
|
|
|
# $c - contents after child processing |
1221
|
|
|
|
|
|
|
# $q - element name (tag) |
1222
|
|
|
|
|
|
|
# %v - hash of attributes |
1223
|
|
|
|
|
|
|
|
1224
|
|
|
|
|
|
|
my %handler=( |
1225
|
|
|
|
|
|
|
# '-outputenc' => 'ISO-8859-1', |
1226
|
|
|
|
|
|
|
# '-default' => sub{"<$q>$c$q>"}, |
1227
|
|
|
|
|
|
|
END |
1228
|
1
|
|
|
|
|
3
|
print $HTML; |
1229
|
1
|
|
|
|
|
8
|
for $name (sort keys %element) { |
1230
|
3
|
|
|
|
|
8
|
print " '$name' => sub{ }, #"; |
1231
|
3
|
|
|
|
|
8
|
print " $element{$name} occurrences;"; |
1232
|
|
|
|
|
|
|
print ' attributes: ', |
1233
|
3
|
100
|
|
|
|
6
|
join(', ', keys %{$att{$name}}) if $att{$name}; |
|
2
|
|
|
|
|
5
|
|
1234
|
|
|
|
|
|
|
# print " \"\$q:\$c\"\n"; |
1235
|
3
|
|
|
|
|
6
|
print "\n"; |
1236
|
|
|
|
|
|
|
} |
1237
|
1
|
|
|
|
|
3
|
print <<'END'; |
1238
|
|
|
|
|
|
|
); |
1239
|
|
|
|
|
|
|
print dt($filename, %handler); |
1240
|
|
|
|
|
|
|
END |
1241
|
|
|
|
|
|
|
} |
1242
|
1
|
|
|
|
|
11
|
); |
1243
|
|
|
|
|
|
|
|
1244
|
1
|
|
|
|
|
3
|
my $file = shift(@files); |
1245
|
1
|
|
|
|
|
16
|
while($file =~ /^-/){ |
1246
|
0
|
0
|
|
|
|
0
|
if ($file eq "-html") { |
|
|
0
|
|
|
|
|
|
1247
|
0
|
|
|
|
|
0
|
$HTML = " '-html' => 1,\n"; |
1248
|
0
|
|
|
|
|
0
|
$mkdtskel{'-html'} = 1;} |
1249
|
0
|
|
|
|
|
0
|
elsif($file eq "-latin1") { $mkdtskel{'-inputenc'}='ISO-8859-1';} |
1250
|
0
|
|
|
|
|
0
|
else { die("usage mktskel [-html] [-latin1] file \n")} |
1251
|
0
|
|
|
|
|
0
|
$file=shift(@files)} |
1252
|
|
|
|
|
|
|
|
1253
|
1
|
|
|
|
|
10
|
dt($file,%mkdtskel) |
1254
|
|
|
|
|
|
|
} |
1255
|
|
|
|
|
|
|
|
1256
|
|
|
|
|
|
|
|
1257
|
|
|
|
|
|
|
|
1258
|
|
|
|
|
|
|
sub _nodeAttributes { |
1259
|
213
|
|
|
213
|
|
227
|
my $node = shift; |
1260
|
213
|
|
|
|
|
238
|
my %answer = (); |
1261
|
213
|
|
|
|
|
416
|
my @attrs = $node->getAttributes(); |
1262
|
213
|
|
|
|
|
301
|
for (@attrs) { |
1263
|
37
|
50
|
|
|
|
64
|
if (ref($_) eq "XML::LibXML::Namespace") { |
1264
|
|
|
|
|
|
|
# TODO: This should not be ignored, I think. |
1265
|
|
|
|
|
|
|
# This sould be converted on a standard attribute with |
1266
|
|
|
|
|
|
|
# key 'namespace' and respective contents |
1267
|
|
|
|
|
|
|
} else { |
1268
|
37
|
|
|
|
|
177
|
$answer{$_->getName()} = $_->getValue(); |
1269
|
|
|
|
|
|
|
} |
1270
|
|
|
|
|
|
|
} |
1271
|
213
|
|
|
|
|
464
|
return %answer; |
1272
|
|
|
|
|
|
|
} |
1273
|
|
|
|
|
|
|
|
1274
|
|
|
|
|
|
|
|
1275
|
|
|
|
|
|
|
sub mkdtdskel { |
1276
|
0
|
|
|
0
|
1
|
0
|
my @files = @_; |
1277
|
0
|
|
|
|
|
0
|
my $name; |
1278
|
|
|
|
|
|
|
my %att; |
1279
|
0
|
|
|
|
|
0
|
my %ele; |
1280
|
0
|
|
|
|
|
0
|
my %elel; |
1281
|
0
|
|
|
|
|
0
|
my $root; |
1282
|
|
|
|
|
|
|
my %handler=( |
1283
|
|
|
|
|
|
|
'-outputenc' => 'ISO-8859-1', |
1284
|
|
|
|
|
|
|
'-default' => sub{ |
1285
|
0
|
|
|
0
|
|
0
|
$elel{$q}++; |
1286
|
0
|
0
|
|
|
|
0
|
$root = $q unless ctxt(1); |
1287
|
0
|
|
|
|
|
0
|
$ele{ctxt(1)}{$q} ++; |
1288
|
0
|
|
|
|
|
0
|
for(keys(%v)){$att{$q}{$_} ++ } ; |
|
0
|
|
|
|
|
0
|
|
1289
|
|
|
|
|
|
|
}, |
1290
|
0
|
0
|
|
0
|
|
0
|
'-pcdata' => sub{ if ($c =~ /[^ \t\n]/){ $ele{ctxt(1)}{"#PCDATA"}=1 }}, |
|
0
|
|
|
|
|
0
|
|
1291
|
0
|
|
|
|
|
0
|
); |
1292
|
|
|
|
|
|
|
|
1293
|
0
|
|
|
|
|
0
|
while($files[0] =~ /^-/){ |
1294
|
0
|
0
|
|
|
|
0
|
if ($files[0] eq "-html") { $handler{'-html'} = 1;} |
|
0
|
0
|
|
|
|
0
|
|
1295
|
0
|
|
|
|
|
0
|
elsif($files[0] eq "-latin1") { $handler{'-inputenc'}='ISO-8859-1';} |
1296
|
0
|
|
|
|
|
0
|
else { die("usage mkdtdskel [-html] [-latin1] file* \n")} |
1297
|
0
|
|
|
|
|
0
|
shift(@files)} |
1298
|
|
|
|
|
|
|
|
1299
|
0
|
|
|
|
|
0
|
for my $filename (@files){ |
1300
|
0
|
|
|
|
|
0
|
dt($filename,%handler); |
1301
|
|
|
|
|
|
|
} |
1302
|
|
|
|
|
|
|
|
1303
|
0
|
|
|
|
|
0
|
print "\n\n"; |
1304
|
0
|
|
|
|
|
0
|
delete $elel{$root}; |
1305
|
|
|
|
|
|
|
|
1306
|
0
|
|
|
|
|
0
|
for ($root, keys %elel){ |
1307
|
0
|
|
|
|
|
0
|
_putele($_, \%ele); |
1308
|
0
|
|
|
|
|
0
|
for $name (keys(%{$att{$_}})) { |
|
0
|
|
|
|
|
0
|
|
1309
|
0
|
|
|
|
|
0
|
print( "\t\n"); |
1310
|
0
|
|
|
|
|
0
|
print( "\t\n"); |
1311
|
|
|
|
|
|
|
} |
1312
|
|
|
|
|
|
|
} |
1313
|
|
|
|
|
|
|
} |
1314
|
|
|
|
|
|
|
|
1315
|
|
|
|
|
|
|
sub _putele { |
1316
|
0
|
|
|
0
|
|
0
|
my ($e,$ele) = @_; |
1317
|
0
|
|
|
|
|
0
|
my @f ; |
1318
|
0
|
0
|
|
|
|
0
|
if ($ele->{$e}) { |
1319
|
0
|
|
|
|
|
0
|
@f = keys %{$ele->{$e}}; |
|
0
|
|
|
|
|
0
|
|
1320
|
0
|
0
|
0
|
|
|
0
|
print "
|
1321
|
|
|
|
|
|
|
(@f >= 1 && $f[0] eq "#PCDATA" ? "" : "*"), |
1322
|
|
|
|
|
|
|
" >\n"; |
1323
|
0
|
|
|
|
|
0
|
print "\n"; |
|
0
|
|
|
|
|
0
|
|
1324
|
|
|
|
|
|
|
} |
1325
|
|
|
|
|
|
|
else { |
1326
|
0
|
|
|
|
|
0
|
print "\n"; |
1327
|
|
|
|
|
|
|
} |
1328
|
|
|
|
|
|
|
} |
1329
|
|
|
|
|
|
|
|
1330
|
|
|
|
|
|
|
sub _whitepc { |
1331
|
13
|
100
|
|
13
|
|
85
|
$_[1] eq '-pcdata' and $_[0] =~ /^[ \t\r\n]*$/ |
1332
|
|
|
|
|
|
|
} |
1333
|
|
|
|
|
|
|
|
1334
|
|
|
|
|
|
|
sub MMAPON { |
1335
|
0
|
|
|
0
|
1
|
0
|
bless([@_],"mmapon") |
1336
|
|
|
|
|
|
|
} |
1337
|
|
|
|
|
|
|
|
1338
|
|
|
|
|
|
|
|
1339
|
|
|
|
|
|
|
sub _fromUTF8 { |
1340
|
4
|
|
|
4
|
|
8
|
my $string = shift; |
1341
|
4
|
|
|
|
|
5
|
my $encode = shift; |
1342
|
4
|
|
|
|
|
5
|
my $ans = eval { XML::LibXML::decodeFromUTF8($encode, $string) }; |
|
4
|
|
|
|
|
24
|
|
1343
|
4
|
50
|
|
|
|
7
|
if ($@) { |
1344
|
0
|
|
|
|
|
0
|
return $string |
1345
|
|
|
|
|
|
|
} else { |
1346
|
4
|
|
|
|
|
9
|
return $ans |
1347
|
|
|
|
|
|
|
} |
1348
|
|
|
|
|
|
|
} |
1349
|
|
|
|
|
|
|
|
1350
|
|
|
|
|
|
|
1; |