1#!/usr/bin/perl -w
2use strict;
3use warnings;
4use Test::More;
5
6use XML::LibXML;
7
8BEGIN{
9  if (1000*$] < 5008) {
10     plan skip_all => "Reader interface only supported in Perl >= 5.8";
11     exit;
12  } elsif (XML::LibXML::LIBXML_VERSION() <= 20620) {
13     plan skip_all => "Reader not supported for libxml2 <= 2.6.20";
14     exit;
15  } else {
16     plan tests => 93;
17  }
18
19  use_ok('XML::LibXML::Reader');
20};
21
22my $file = "test/textReader/countries.xml";
23{
24  my $reader = new XML::LibXML::Reader(location => $file, {expand_entities => 1});
25  isa_ok($reader, "XML::LibXML::Reader");
26  is($reader->read, 1, "read");
27  is($reader->byteConsumed, 488, "byteConsumed");
28  is($reader->attributeCount, 0, "attributeCount");
29  is($reader->baseURI, $file, "baseURI");
30  is($reader->encoding, 'UTF-8', "encoding");
31  is($reader->localName, 'countries', "localName");
32  is($reader->name, 'countries', "name");
33  is($reader->prefix, undef, "prefix");
34  is($reader->value, undef, "value");
35  is($reader->xmlLang, undef, "xmlLang");
36  is($reader->xmlVersion, '1.0', "xmlVersion");
37  $reader->read;
38  $reader->read;
39  $reader->read;		# skipping to country node
40  is($reader->name, 'country', "skipping to country");
41  is($reader->depth, "1", "depth");
42  is($reader->getAttribute("acronym"), "AL", "getAttribute");
43  is($reader->getAttributeNo(0), "AL", "getAttributeNo");
44  is($reader->getAttributeNs("acronym", undef), "AL", "getAttributeNs");
45  is($reader->lineNumber, "20", "lineNumber");
46  is($reader->columnNumber, "1", "columnNumber");
47  ok($reader->hasAttributes, "hasAttributes");
48  ok(! $reader->hasValue, "hasValue");
49  ok(! $reader->isDefault, "isDefault");
50  ok(! $reader->isEmptyElement, "isEmptyElement");
51  ok(! $reader->isNamespaceDecl, "isNamespaceDecl");
52  ok(! $reader->isValid, "isValid");
53  is($reader->localName, "country", "localName");
54  is($reader->lookupNamespace(undef), undef, "lookupNamespace");
55
56  ok($reader->moveToAttribute("acronym"), "moveToAttribute");
57  ok($reader->moveToAttributeNo(0), "moveToAttributeNo");
58  ok($reader->moveToAttributeNs("acronym", undef), "moveToAttributeNs");
59
60  ok($reader->moveToElement, "moveToElement");
61  ok($reader->moveToFirstAttribute, "moveToFirstAttribute");
62  ok($reader->moveToNextAttribute, "moveToNextAttribute");
63  ok($reader->readAttributeValue, "attributeValue");
64
65  $reader->moveToElement;
66  is($reader->name, "country", "name");
67  is($reader->namespaceURI, undef, "namespaceURI");
68
69  ok($reader->nextSibling, "nextSibling");
70  is($reader->nodeType, XML_READER_TYPE_SIGNIFICANT_WHITESPACE, "nodeType");
71  is($reader->prefix, undef, "prefix");
72
73  is($reader->readInnerXml, "", "readInnerXml");
74  is($reader->readOuterXml, "\n", "readOuterXml");
75  ok($reader->readState, "readState");
76
77  is($reader->getParserProp('expand_entities'), 1, "getParserProp");
78
79  ok($reader->standalone, "standalone");
80  is($reader->value, "\n", "value");
81  is($reader->xmlLang, undef, "xmlLang");
82
83
84  ok($reader->close, "close");
85}
86
87
88my $fd;
89# FD interface
90for my $how (qw(FD IO)) {
91#  my $fd;
92  open $fd, $file or die "cannot open $file: $!\n";
93  my $reader = new XML::LibXML::Reader($how => $fd, URI => $file);
94  isa_ok($reader, "XML::LibXML::Reader");
95  $reader->read;
96  $reader->read;
97  is($reader->name, "countries","name in fd");
98  $reader->read;
99  $reader->read;
100  $reader->read;
101  close $fd;
102}
103
104# scalar interface
105{
106  open my $fd, $file or die "cannot open $file: $!\n";
107  my $doc;
108  {
109    local $/;
110    $doc = <$fd>;
111  }
112  close $fd;
113  my $reader = new XML::LibXML::Reader(string => $doc, URI => $file);
114  isa_ok($reader, "XML::LibXML::Reader");
115  $reader->read;
116  $reader->read;
117  is($reader->name, "countries","name in string");
118}
119
120# DOM
121{
122  my $DOM = XML::LibXML->new->parse_file($file);
123  my $reader = new XML::LibXML::Reader(DOM => $DOM);
124  isa_ok($reader, "XML::LibXML::Reader");
125  $reader->read;
126  $reader->read;
127  is($reader->name, "countries","name in string");
128  ok($reader->document,"document");
129  ok($reader->document->isSameNode($DOM),"document is DOM");
130}
131
132# Expand
133{
134  my ($node1,$node2, $node3);
135  my $xml = <<'EOF';
136<root>
137  <AA foo="FOO"> text1 <inner/> </AA>
138  <DD/><BB bar="BAR">text2<CC> xx </CC>foo<FF/> </BB>x
139  <EE baz="BAZ"> xx <PP>preserved</PP> yy <XX>FOO</XX></EE>
140  <a/>
141  <b/>
142  <x:ZZ xmlns:x="foo"/>
143  <QQ/>
144  <YY/>
145</root>
146EOF
147  {
148    my $reader = new XML::LibXML::Reader(string => $xml);
149    $reader->preservePattern('//PP');
150    $reader->preservePattern('//x:ZZ',{ x => "foo"});
151
152    isa_ok($reader, "XML::LibXML::Reader");
153    $reader->nextElement;
154    is($reader->name, "root","root node");
155    $reader->nextElement;
156    $node1 = $reader->copyCurrentNode(1);
157    is($node1->nodeName, "AA","deep copy node");
158    $reader->next;
159    ok($reader->nextElement("DD"),"next named element");
160    is($reader->name, "DD","name");
161    is($reader->readOuterXml, "<DD/>","readOuterXml");
162    ok($reader->read,"read");
163    is($reader->name, "BB","name");
164    $node2 = $reader->copyCurrentNode(0);
165    is($node2->nodeName, "BB","shallow copy node");
166    $reader->nextElement;
167    is($reader->name, "CC","nextElement");
168    $reader->nextSibling;
169    is( $reader->nodeType(), XML_READER_TYPE_TEXT, "text node" );
170    is( $reader->value,"foo", "text content" );
171    $reader->skipSiblings;
172    is( $reader->nodeType(), XML_READER_TYPE_END_ELEMENT, "end element type" );
173    $reader->nextElement;
174    is($reader->name, "EE","name");
175    ok($reader->nextSiblingElement("ZZ","foo"),"namespace");
176    is($reader->namespaceURI, "foo","namespaceURI");
177    $reader->nextElement;
178    $node3= $reader->preserveNode;
179    is( $reader->readOuterXml(), $node3->toString(),"outer xml");
180    ok($node3,"preserve node");
181    $reader->finish;
182    my $doc = $reader->document;
183    ok($doc, "document");
184    ok($doc->documentElement, "doc root element");
185    is($doc->documentElement->toString,q(<root><EE baz="BAZ"><PP>preserved</PP></EE><x:ZZ xmlns:x="foo"/><QQ/></root>),
186       "preserved content");
187  }
188  ok($node1->hasChildNodes,"copy w/  child nodes");
189  ok($node1->toString(),q(<AA foo="FOO"> text1 <inner/> </AA>));
190  ok(!defined $node2->firstChild, "copy w/o child nodes");
191  ok($node2->toString(),q(<BB bar="BAR"/>));
192  ok($node3->toString(),q(<QQ/>));
193}
194
195{
196  my $bad_xml = <<'EOF';
197<root>
198  <x>
199     foo
200  </u>
201</root>
202EOF
203  my $reader = new XML::LibXML::Reader(
204    string => $bad_xml,
205    URI => "mystring.xml"
206   );
207  eval { $reader->finish };
208  ok((defined $@ and $@ =~ /in mystring.xml at line 2:/), 'catchin error');
209}
210
211{
212  my $rng = "test/relaxng/demo.rng";
213  for my $RNG ($rng, XML::LibXML::RelaxNG->new(location => $rng)) {
214    {
215      my $reader = new XML::LibXML::Reader(
216	location => "test/relaxng/demo.xml",
217	RelaxNG => $RNG,
218       );
219      ok($reader->finish, "validate using ".(ref($RNG) ? 'XML::LibXML::RelaxNG' : 'RelaxNG file'));
220    }
221    {
222      my $reader = new XML::LibXML::Reader(
223	location => "test/relaxng/invaliddemo.xml",
224	RelaxNG => $RNG,
225       );
226      eval { $reader->finish };
227      ok($@, "catch validation error for ".(ref($RNG) ? 'XML::LibXML::RelaxNG' : 'RelaxNG file'));
228    }
229
230  }
231}
232
233{
234  my $xsd = "test/schema/schema.xsd";
235  for my $XSD ($xsd, XML::LibXML::Schema->new(location => $xsd)) {
236    {
237      my $reader = new XML::LibXML::Reader(
238	location => "test/schema/demo.xml",
239	Schema => $XSD,
240       );
241      ok($reader->finish, "validate using ".(ref($XSD) ? 'XML::LibXML::Schema' : 'Schema file'));
242    }
243    {
244      my $reader = new XML::LibXML::Reader(
245	location => "test/schema/invaliddemo.xml",
246	Schema => $XSD,
247       );
248      eval { $reader->finish };
249      ok($@, "catch validation error for ".(ref($XSD) ? 'XML::LibXML::Schema' : 'Schema file'));
250    }
251
252  }
253}
254