1#[allow(unused, deprecated)] use std::ascii::AsciiExt;
19use std::collections::{BTreeSet, HashMap};
20use std::mem::replace;
21use std::ops::Deref;
22use std::{char, error, fmt, iter};
23
24use peresil::{self,StringPoint,ParseMaster,Recoverable};
25
26use self::Reference::*;
27
28use super::{PrefixedName,QName};
29use super::dom;
30use super::str::XmlStr;
31
32#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
33enum SpecificError {
34 Expected(&'static str),
35
36 ExpectedAttribute,
37 ExpectedAttributeValue,
38
39 ExpectedCData,
40
41 ExpectedCharacterData,
42
43 ExpectedComment,
44 ExpectedCommentBody,
45
46 ExpectedElement,
47 ExpectedElementName,
48 ExpectedElementEnd,
49 ExpectedElementSelfClosed,
50
51 ExpectedProcessingInstruction,
52 ExpectedProcessingInstructionTarget,
53 ExpectedProcessingInstructionValue,
54
55 ExpectedVersionNumber,
56 ExpectedEncoding,
57 ExpectedYesNo,
58 ExpectedWhitespace,
59
60 ExpectedDocumentTypeName,
61 ExpectedIntSubset,
62 ExpectedSystemLiteral,
63
64 ExpectedClosingQuote(&'static str),
65 ExpectedOpeningQuote(&'static str),
66
67 ExpectedDecimalReferenceValue,
68 ExpectedHexReferenceValue,
69 ExpectedNamedReferenceValue,
70
71 ExpectedDecimalReference,
72 ExpectedHexReference,
73 ExpectedNamedReference,
74
75 InvalidProcessingInstructionTarget,
76 MismatchedElementEndName,
77
78 InvalidDecimalReference,
79 InvalidHexReference,
80 UnknownNamedReference,
81
82 DuplicateAttribute,
83 RedefinedNamespace,
84 RedefinedDefaultNamespace,
85 EmptyNamespace,
86 UnknownNamespacePrefix,
87 UnclosedElement,
88}
89
90impl Recoverable for SpecificError {
91 fn recoverable(&self) -> bool {
92 use self::SpecificError::*;
93
94 match *self {
95 ExpectedEncoding |
96 ExpectedYesNo |
97 InvalidProcessingInstructionTarget |
98 MismatchedElementEndName |
99 InvalidDecimalReference |
100 InvalidHexReference |
101 UnknownNamedReference |
102 DuplicateAttribute |
103 RedefinedNamespace |
104 RedefinedDefaultNamespace |
105 EmptyNamespace |
106 UnknownNamespacePrefix |
107 UnclosedElement => {
108 false
109 },
110 _ => true
111 }
112 }
113}
114
115impl fmt::Display for SpecificError {
116 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
117 use self::error::Error;
118 use self::SpecificError::*;
119
120 match *self {
121 Expected(s) |
122 ExpectedClosingQuote(s) |
123 ExpectedOpeningQuote(s) => {
124 write!(f, "Parser error: {} {}", self.description(), s)
125 },
126 _ => write!(f, "Parser error: {}", self.description())
127 }
128 }
129}
130
131impl error::Error for SpecificError {
132 fn description(&self) -> &str {
133 use self::SpecificError::*;
134
135 match *self {
136 Expected(_) => "expected",
137 ExpectedAttribute => "expected attribute",
138 ExpectedAttributeValue => "expected attribute value",
139 ExpectedCData => "expected CDATA",
140 ExpectedCharacterData => "expected character data",
141 ExpectedComment => "expected comment",
142 ExpectedCommentBody => "expected comment body",
143 ExpectedElement => "expected element",
144 ExpectedElementName => "expected element name",
145 ExpectedElementEnd => "expected element end",
146 ExpectedElementSelfClosed => "expected element self closed",
147 ExpectedProcessingInstruction => "expected processing instruction",
148 ExpectedProcessingInstructionTarget => "expected processing instruction target",
149 ExpectedProcessingInstructionValue => "expected processing instruction value",
150 ExpectedVersionNumber => "expected version number",
151 ExpectedEncoding => "expected encoding",
152 ExpectedYesNo => "expected yes or no",
153 ExpectedWhitespace => "expected whitespace",
154 ExpectedDocumentTypeName => "expected document type name",
155 ExpectedIntSubset => "expected int subset",
156 ExpectedSystemLiteral => "expected system literal",
157 ExpectedClosingQuote(_) => "expected closing quote",
158 ExpectedOpeningQuote(_) => "expected opening quote",
159 ExpectedDecimalReferenceValue => "expected decimal reference value",
160 ExpectedHexReferenceValue => "expected hex reference value",
161 ExpectedNamedReferenceValue => "expected named reference value",
162 ExpectedDecimalReference => "expected decimal reference",
163 ExpectedHexReference => "expected hex reference",
164 ExpectedNamedReference => "expected named reference",
165 InvalidProcessingInstructionTarget => "invalid processing instruction target",
166 MismatchedElementEndName => "mismatched element end name",
167 InvalidDecimalReference => "invalid decimal reference",
168 InvalidHexReference => "invalid hex reference",
169 UnknownNamedReference => "unknown named reference",
170 DuplicateAttribute => "duplicate attribute",
171 RedefinedNamespace => "redefined namespace",
172 RedefinedDefaultNamespace => "redefined default namespace",
173 EmptyNamespace => "empty namespace",
174 UnknownNamespacePrefix => "unknown namespace prefix",
175 UnclosedElement => "unclosed element",
176 }
177 }
178}
179
180type XmlMaster<'a> = peresil::ParseMaster<StringPoint<'a>, SpecificError>;
181type XmlProgress<'a, T> = peresil::Progress<StringPoint<'a>, T, SpecificError>;
182
183fn success<T>(data: T, point: StringPoint) -> XmlProgress<T> {
184 peresil::Progress { point: point, status: peresil::Status::Success(data) }
185}
186
187#[derive(Debug,Copy,Clone)]
189struct Span<T> {
190 offset: usize,
191 value: T,
192}
193
194impl<T> Span<T> {
195 fn parse<'a, F>(pt: StringPoint<'a>, f: F) -> XmlProgress<'a, Span<T>>
197 where F: Fn(StringPoint<'a>) -> XmlProgress<'a, T>
198 {
199 let (after, v) = try_parse!(f(pt));
200 let span = Span { value: v, offset: pt.offset };
201 peresil::Progress { status: peresil::Status::Success(span), point: after }
202 }
203
204 fn map<F, U>(self, f: F) -> Span<U>
205 where F: FnOnce(T) -> U
206 {
207 Span { value: f(self.value), offset: self.offset }
208 }
209}
210
211#[derive(Debug,Copy,Clone)]
212enum Reference<'a> {
213 EntityReference(Span<&'a str>),
214 DecimalCharReference(Span<&'a str>),
215 HexCharReference(Span<&'a str>),
216}
217
218pub trait XmlParseExt<'a> {
220 fn consume_space(&self) -> peresil::Progress<StringPoint<'a>, &'a str, ()>;
222 fn consume_decimal_chars(&self) -> peresil::Progress<StringPoint<'a>, &'a str, ()>;
224 fn consume_ncname(&self) -> peresil::Progress<StringPoint<'a>, &'a str, ()>;
226 fn consume_prefixed_name(&self) -> peresil::Progress<StringPoint<'a>, PrefixedName<'a>, ()>;
228}
229
230impl<'a> XmlParseExt<'a> for StringPoint<'a> {
231 fn consume_space(&self) -> peresil::Progress<StringPoint<'a>, &'a str, ()> {
232 self.consume_to(self.s.end_of_space())
233 }
234
235 fn consume_decimal_chars(&self) -> peresil::Progress<StringPoint<'a>, &'a str, ()> {
236 self.consume_to(self.s.end_of_decimal_chars())
237 }
238
239 fn consume_ncname(&self) -> peresil::Progress<StringPoint<'a>, &'a str, ()> {
240 self.consume_to(self.s.end_of_ncname())
241 }
242
243 fn consume_prefixed_name(&self) -> peresil::Progress<StringPoint<'a>, PrefixedName<'a>, ()> {
244 fn parse_local(xml: StringPoint) -> peresil::Progress<StringPoint, &str, ()> {
245 let (xml, _) = try_parse!(xml.consume_literal(":"));
246 xml.consume_ncname()
247 }
248
249 let (xml, prefix) = try_parse!(self.consume_ncname());
250 let (xml, local) = parse_local(xml).optional(xml);
251
252 let name = match local {
253 Some(local) => PrefixedName::with_prefix(Some(prefix),local),
254 None => PrefixedName::new(prefix),
255 };
256
257 peresil::Progress { point: xml, status: peresil::Status::Success(name) }
258 }
259}
260
261trait PrivateXmlParseExt<'a> {
262 fn consume_attribute_value(&self, quote: &str) -> XmlProgress<'a, &'a str>;
263 fn consume_name(&self) -> peresil::Progress<StringPoint<'a>, &'a str, ()>;
264 fn consume_hex_chars(&self) -> XmlProgress<'a, &'a str>;
265 fn consume_char_data(&self) -> XmlProgress<'a, &'a str>;
266 fn consume_cdata(&self) -> XmlProgress<'a, &'a str>;
267 fn consume_int_subset(&self) -> XmlProgress<'a, &'a str>;
268 fn consume_comment(&self) -> XmlProgress<'a, &'a str>;
269 fn consume_pi_value(&self) -> XmlProgress<'a, &'a str>;
270 fn consume_start_tag(&self) -> XmlProgress<'a, &'a str>;
271 fn consume_encoding(&self) -> XmlProgress<'a, &'a str>;
272}
273
274impl<'a> PrivateXmlParseExt<'a> for StringPoint<'a> {
275 fn consume_attribute_value(&self, quote: &str) -> XmlProgress<'a, &'a str> {
276 self.consume_to(self.s.end_of_attribute(quote)).map_err(|_| SpecificError::ExpectedAttributeValue)
277 }
278
279 fn consume_name(&self) -> peresil::Progress<StringPoint<'a>, &'a str, ()> {
280 self.consume_to(self.s.end_of_name())
281 }
282
283 fn consume_hex_chars(&self) -> XmlProgress<'a, &'a str> {
284 self.consume_to(self.s.end_of_hex_chars()).map_err(|_| SpecificError::ExpectedHexReferenceValue)
285 }
286
287 fn consume_char_data(&self) -> XmlProgress<'a, &'a str> {
288 self.consume_to(self.s.end_of_char_data()).map_err(|_| SpecificError::ExpectedCharacterData)
289 }
290
291 fn consume_cdata(&self) -> XmlProgress<'a, &'a str> {
292 self.consume_to(self.s.end_of_cdata()).map_err(|_| SpecificError::ExpectedCData)
293 }
294
295 fn consume_int_subset(&self) -> XmlProgress<'a, &'a str> {
296 self.consume_to(self.s.end_of_int_subset()).map_err(|_| SpecificError::ExpectedIntSubset)
297 }
298
299 fn consume_comment(&self) -> XmlProgress<'a, &'a str> {
300 self.consume_to(self.s.end_of_comment()).map_err(|_| SpecificError::ExpectedCommentBody)
301 }
302
303 fn consume_pi_value(&self) -> XmlProgress<'a, &'a str> {
304 self.consume_to(self.s.end_of_pi_value()).map_err(|_| SpecificError::ExpectedProcessingInstructionValue)
305 }
306
307 fn consume_start_tag(&self) -> XmlProgress<'a, &'a str> {
308 self.consume_to(self.s.end_of_start_tag()).map_err(|_| SpecificError::ExpectedElement)
309 }
310
311 fn consume_encoding(&self) -> XmlProgress<'a, &'a str> {
312 self.consume_to(self.s.end_of_encoding()).map_err(|_| SpecificError::ExpectedEncoding)
313 }
314}
315
316trait X<'a> {
317 fn expect_space(&self) -> XmlProgress<'a, &'a str>;
318 fn expect_literal(&self, s: &'static str) -> XmlProgress<'a, &'a str>;
319}
320
321impl<'a> X<'a> for StringPoint<'a> {
322 fn expect_space(&self) -> XmlProgress<'a, &'a str> {
323 self.consume_space().map_err(|_| SpecificError::ExpectedWhitespace)
324 }
325
326 fn expect_literal(&self, s: &'static str) -> XmlProgress<'a, &'a str> {
327 self.consume_literal(s).map_err(|_| SpecificError::Expected(s))
328 }
329}
330
331#[derive(Debug, Copy, Clone)]
332enum Token<'a> {
333 XmlDeclaration,
334 DocumentTypeDeclaration,
335 Comment(&'a str),
336 ProcessingInstruction(&'a str, Option<&'a str>),
337 Whitespace(&'a str),
338 ElementStart(Span<PrefixedName<'a>>),
339 ElementStartClose,
340 ElementSelfClose,
341 ElementClose(Span<PrefixedName<'a>>),
342 AttributeStart(Span<PrefixedName<'a>>, &'static str),
343 AttributeEnd,
344 LiteralAttributeValue(&'a str),
345 ReferenceAttributeValue(Reference<'a>),
346 CharData(&'a str),
347 CData(&'a str),
348 ContentReference(Reference<'a>),
349}
350
351#[derive(Debug, Copy, Clone)]
352enum State {
353 AtBeginning,
354 AfterDeclaration,
355 AfterElementStart(usize),
356 AfterAttributeStart(usize, &'static str),
357 Content(usize),
358 AfterMainElement,
359}
360
361#[derive(Debug)]
362struct PullParser<'a> {
363 pm: XmlMaster<'a>,
364 xml: StringPoint<'a>,
365 state: State,
366}
367
368impl<'a> PullParser<'a> {
369 fn new(xml: &str) -> PullParser {
370 PullParser {
371 pm: ParseMaster::new(),
372 xml: StringPoint::new(xml),
373 state: State::AtBeginning,
374 }
375 }
376}
377
378fn parse_comment<'a>(xml: StringPoint<'a>) -> XmlProgress<'a, Token> {
379 let (xml, _) = try_parse!(xml.consume_literal("<!--").map_err(|_| SpecificError::ExpectedComment));
380 let (xml, text) = try_parse!(xml.consume_comment());
381 let (xml, _) = try_parse!(xml.expect_literal("-->"));
382
383 success(Token::Comment(text), xml)
384}
385
386fn parse_one_quoted_value<'a, T, F>(xml: StringPoint<'a>, quote: &'static str, f: F)
387 -> XmlProgress<'a, T>
388 where F: FnMut(StringPoint<'a>) -> XmlProgress<'a, T>
389{
390 let mut f = f;
391 let (xml, _) = try_parse!(xml.consume_literal(quote).map_err(|_| SpecificError::ExpectedOpeningQuote(quote)));
392 let (xml, value) = try_parse!(f(xml));
393 let (xml, _) = try_parse!(xml.consume_literal(quote).map_err(|_| SpecificError::ExpectedClosingQuote(quote)));
394
395 success(value, xml)
396}
397
398fn parse_quoted_value<'a, T, F>(pm: &mut XmlMaster<'a>, xml: StringPoint<'a>, f: F) -> XmlProgress<'a, T>
399 where F: FnMut(&mut XmlMaster<'a>, StringPoint<'a>, &str) -> XmlProgress<'a, T>
400{
401 let mut f = f;
402 pm.alternate()
403 .one(|pm| parse_one_quoted_value(xml, "'", |xml| f(pm, xml, "'")))
404 .one(|pm| parse_one_quoted_value(xml, "\"", |xml| f(pm, xml, "\"")))
405 .finish()
406}
407
408fn parse_eq(xml: StringPoint) -> XmlProgress<()> {
409 let (xml, _) = xml.consume_space().optional(xml);
410 let (xml, _) = try_parse!(xml.expect_literal("="));
411 let (xml, _) = xml.consume_space().optional(xml);
412
413 success((), xml)
414}
415
416fn parse_version_info<'a>(pm: &mut XmlMaster<'a>, xml: StringPoint<'a>) -> XmlProgress<'a, &'a str> {
417 fn version_num(xml: StringPoint) -> peresil::Progress<StringPoint, &str, ()> {
418 let start_point = xml;
419
420 let (xml, _) = try_parse!(xml.consume_literal("1."));
421 let (xml, _) = try_parse!(xml.consume_decimal_chars());
422
423 peresil::Progress::success(xml, start_point.to(xml))
424 }
425
426 let (xml, _) = try_parse!(xml.expect_space());
427 let (xml, _) = try_parse!(xml.expect_literal("version"));
428 let (xml, _) = try_parse!(parse_eq(xml));
429 let (xml, version) = try_parse!(
430 parse_quoted_value(pm, xml, |_, xml, _| version_num(xml).map_err(|_| SpecificError::ExpectedVersionNumber))
431 );
432
433 success(version, xml)
434}
435
436fn parse_encoding_declaration<'a>(pm: &mut XmlMaster<'a>, xml: StringPoint<'a>)
437 -> XmlProgress<'a, &'a str>
438{
439 let (xml, _) = try_parse!(xml.expect_space());
440 let (xml, _) = try_parse!(xml.expect_literal("encoding"));
441 let (xml, _) = try_parse!(parse_eq(xml));
442 let (xml, encoding) = try_parse!(
443 parse_quoted_value(pm, xml, |_, xml, _| xml.consume_encoding())
444 );
445
446 success(encoding, xml)
447}
448
449fn parse_standalone_declaration<'a>(pm: &mut XmlMaster<'a>, xml: StringPoint<'a>)
450 -> XmlProgress<'a, &'a str>
451{
452 let (xml, _) = try_parse!(xml.expect_space());
453 let (xml, _) = try_parse!(xml.expect_literal("standalone"));
454 let (xml, _) = try_parse!(parse_eq(xml));
455 let (xml, standalone) = try_parse!(
456 parse_quoted_value(pm, xml, |pm, xml, _| {
457 pm.alternate()
458 .one(|_| xml.expect_literal("yes"))
459 .one(|_| xml.expect_literal("no"))
460 .finish()
461 .map_err(|_| SpecificError::ExpectedYesNo)
462 })
463 );
464
465 success(standalone, xml)
466}
467
468fn parse_xml_declaration<'a>(pm: &mut XmlMaster<'a>, xml: StringPoint<'a>) -> XmlProgress<'a, Token<'a>> {
469 let (xml, _) = try_parse!(xml.expect_literal("<?xml"));
470 let (xml, _version) = try_parse!(parse_version_info(pm, xml));
471 let (xml, _encoding) = try_parse!(pm.optional(xml, |pm, xml| {
472 parse_encoding_declaration(pm, xml)
473 }));
474 let (xml, _standalone) = try_parse!(pm.optional(xml, |pm, xml| {
475 parse_standalone_declaration(pm, xml)
476 }));
477 let (xml, _) = xml.consume_space().optional(xml);
478 let (xml, _) = try_parse!(xml.expect_literal("?>"));
479
480 success(Token::XmlDeclaration, xml)
481}
482
483fn parse_external_id<'a>(pm: &mut XmlMaster<'a>, xml: StringPoint<'a>)
485 -> XmlProgress<'a, &'a str>
486{
487 let (xml, _) = try_parse!(xml.expect_space());
488 let (xml, _) = try_parse!(xml.expect_literal("SYSTEM"));
489 let (xml, _) = try_parse!(xml.expect_space());
490 let (xml, external_id) = try_parse!(
491 parse_quoted_value(pm, xml, |_, xml, quote|
492 xml.consume_attribute_value(quote).map_err(|_| SpecificError::ExpectedSystemLiteral)
493 )
494 );
495
496 success(external_id, xml)
497}
498
499fn parse_int_subset<'a>(_pm: &mut XmlMaster<'a>, xml: StringPoint<'a>)
500 -> XmlProgress<'a, &'a str>
501{
502 let (xml, _) = try_parse!(xml.expect_literal("["));
503 let (xml, _) = xml.consume_space().optional(xml);
504 let (xml, elements) = try_parse!(
505 xml.consume_int_subset().map_err(|_| SpecificError::ExpectedIntSubset)
506 );
507 let (xml, _) = xml.consume_space().optional(xml);
508 let (xml, _) = try_parse!(xml.expect_literal("]"));
509 let (xml, _) = xml.consume_space().optional(xml);
510
511 success(elements, xml)
512}
513
514fn parse_document_type_declaration<'a>(pm: &mut XmlMaster<'a>, xml: StringPoint<'a>) -> XmlProgress<'a, Token<'a>> {
515 let (xml, _) = try_parse!(xml.expect_literal("<!DOCTYPE"));
516 let (xml, _) = try_parse!(xml.expect_space());
517 let (xml, _type_name) = try_parse!(
518 xml.consume_name().map_err(|_| SpecificError::ExpectedDocumentTypeName)
519 );
520 let (xml, _id) = try_parse!(pm.optional(xml, |p, x| parse_external_id(p, x)));
521 let (xml, _) = xml.consume_space().optional(xml);
522 let (xml, _int_subset) = try_parse!(pm.optional(xml, |p, x| parse_int_subset(p, x)));
523 let (xml, _) = try_parse!(xml.expect_literal(">"));
524
525 success(Token::DocumentTypeDeclaration, xml)
526}
527
528fn parse_pi_value(xml: StringPoint) -> XmlProgress<&str> {
529 let (xml, _) = try_parse!(xml.expect_space());
530 xml.consume_pi_value()
531}
532
533fn parse_pi<'a>(xml: StringPoint<'a>) -> XmlProgress<'a, Token> {
534 let (xml, _) = try_parse!(xml.consume_literal("<?").map_err(|_| SpecificError::ExpectedProcessingInstruction));
535 let target_xml = xml;
536 let (xml, target) = try_parse!(xml.consume_name().map_err(|_| SpecificError::ExpectedProcessingInstructionTarget));
537 let (xml, value) = parse_pi_value(xml).optional(xml);
538 let (xml, _) = try_parse!(xml.expect_literal("?>"));
539
540 if target.eq_ignore_ascii_case("xml") {
541 return peresil::Progress::failure(target_xml, SpecificError::InvalidProcessingInstructionTarget);
542 }
543
544 success(Token::ProcessingInstruction(target, value), xml)
545}
546
547fn parse_element_start(xml: StringPoint) -> XmlProgress<Token> {
548 let (xml, _) = try_parse!(xml.consume_start_tag());
549 let (xml, name) = try_parse!(Span::parse(xml, |xml| xml.consume_prefixed_name().map_err(|_| SpecificError::ExpectedElementName)));
550
551 success(Token::ElementStart(name), xml)
552}
553
554fn parse_element_start_close(xml: StringPoint) -> XmlProgress<Token> {
555 let (xml, _) = xml.expect_space().optional(xml);
556
557 xml.consume_literal(">")
558 .map(|_| Token::ElementStartClose)
559 .map_err(|_| SpecificError::ExpectedElementEnd)
560}
561
562fn parse_element_self_close(xml: StringPoint) -> XmlProgress<Token> {
563 let (xml, _) = xml.expect_space().optional(xml);
564
565 xml.consume_literal("/>")
566 .map(|_| Token::ElementSelfClose)
567 .map_err(|_| SpecificError::ExpectedElementSelfClosed)
568}
569
570fn parse_element_close(xml: StringPoint) -> XmlProgress<Token> {
571 let (xml, _) = try_parse!(xml.expect_literal("</"));
572
573 let (xml, name) = try_parse!(Span::parse(xml, |xml| xml.consume_prefixed_name().map_err(|_| SpecificError::ExpectedElementName)));
574
575 let (xml, _) = xml.consume_space().optional(xml);
576 let (xml, _) = try_parse!(xml.expect_literal(">"));
577
578 success(Token::ElementClose(name), xml)
579}
580
581const QUOT: &'static str = r#"""#;
582const APOS: &'static str = r#"'"#;
583
584fn parse_attribute_start<'a>(pm: &mut XmlMaster<'a>, xml: StringPoint<'a>) -> XmlProgress<'a, Token<'a>> {
585 let (xml, _) = try_parse!(xml.expect_space());
586
587 let (xml, name) = try_parse!(Span::parse(xml, |xml| xml.consume_prefixed_name().map_err(|_| SpecificError::ExpectedAttribute)));
588
589 let (xml, _) = try_parse!(parse_eq(xml));
590
591 let (xml, q) = try_parse!(
592 pm.alternate()
593 .one(|_| xml.expect_literal(QUOT).map_err(|_| SpecificError::ExpectedOpeningQuote(QUOT)))
594 .one(|_| xml.expect_literal(APOS).map_err(|_| SpecificError::ExpectedOpeningQuote(APOS)))
595 .finish());
596
597 let q = if q == QUOT { QUOT } else { APOS };
598
599 success(Token::AttributeStart(name, q), xml)
600}
601
602fn parse_attribute_end<'a>(xml: StringPoint<'a>, quote: &'static str) -> XmlProgress<'a, Token<'a>> {
603 xml.consume_literal(quote)
604 .map(|_| Token::AttributeEnd)
605 .map_err(|_| SpecificError::ExpectedClosingQuote(quote))
606}
607
608fn parse_attribute_literal<'a>(xml: StringPoint<'a>, quote: &str) -> XmlProgress<'a, Token<'a>> {
609 let (xml, val) = try_parse!(xml.consume_attribute_value(quote));
610
611 success(Token::LiteralAttributeValue(val), xml)
612}
613
614fn parse_entity_ref(xml: StringPoint) -> XmlProgress<Reference> {
615 let (xml, _) = try_parse!(xml.consume_literal("&").map_err(|_| SpecificError::ExpectedNamedReference));
616 let (xml, name) = try_parse!(Span::parse(xml, |xml| xml.consume_name().map_err(|_| SpecificError::ExpectedNamedReferenceValue)));
617 let (xml, _) = try_parse!(xml.expect_literal(";"));
618
619 success(EntityReference(name), xml)
620}
621
622fn parse_decimal_char_ref(xml: StringPoint) -> XmlProgress<Reference> {
623 let (xml, _) = try_parse!(xml.consume_literal("&#").map_err(|_| SpecificError::ExpectedDecimalReference));
624 let (xml, dec) = try_parse!(Span::parse(xml, |xml| xml.consume_decimal_chars().map_err(|_| SpecificError::ExpectedDecimalReferenceValue)));
625 let (xml, _) = try_parse!(xml.expect_literal(";"));
626
627 success(DecimalCharReference(dec), xml)
628}
629
630fn parse_hex_char_ref(xml: StringPoint) -> XmlProgress<Reference> {
631 let (xml, _) = try_parse!(xml.consume_literal("&#x").map_err(|_| SpecificError::ExpectedHexReference));
632 let (xml, hex) = try_parse!(Span::parse(xml, |xml| xml.consume_hex_chars()));
633 let (xml, _) = try_parse!(xml.expect_literal(";"));
634
635 success(HexCharReference(hex), xml)
636}
637
638fn parse_reference<'a>(pm: &mut XmlMaster<'a>, xml: StringPoint<'a>) -> XmlProgress<'a, Reference<'a>> {
639 pm.alternate()
640 .one(|_| parse_entity_ref(xml))
641 .one(|_| parse_decimal_char_ref(xml))
642 .one(|_| parse_hex_char_ref(xml))
643 .finish()
644}
645
646fn parse_attribute_reference<'a>(pm: &mut XmlMaster<'a>, xml: StringPoint<'a>) -> XmlProgress<'a, Token<'a>> {
647 let (xml, val) = try_parse!(parse_reference(pm, xml));
648
649 success(Token::ReferenceAttributeValue(val), xml)
650}
651
652fn parse_char_data<'a>(xml: StringPoint<'a>) -> XmlProgress<'a, Token> {
653 xml.consume_char_data()
654 .map(Token::CharData)
655}
656
657fn parse_cdata<'a>(xml: StringPoint<'a>) -> XmlProgress<'a, Token> {
658 let (xml, _) = try_parse!(xml.expect_literal("<![CDATA["));
659 let (xml, text) = try_parse!(xml.consume_cdata());
660 let (xml, _) = try_parse!(xml.expect_literal("]]>"));
661
662 success(Token::CData(text), xml)
663}
664
665fn parse_content_reference<'a>(pm: &mut XmlMaster<'a>, xml: StringPoint<'a>) -> XmlProgress<'a, Token<'a>> {
666 let (xml, r) = try_parse!(parse_reference(pm, xml));
667 success(Token::ContentReference(r), xml)
668}
669
670impl<'a> Iterator for PullParser<'a> {
671 type Item = Result<Token<'a>, (usize, Vec<SpecificError>)>;
672
673 fn next(&mut self) -> Option<Self::Item> {
674 let pm = &mut self.pm;
675 let xml = self.xml;
676
677 let r = match self.state {
678 State::AtBeginning => {
679 pm.alternate()
680 .one(|pm| parse_xml_declaration(pm, xml))
681 .one(|_| parse_element_start(xml))
682 .one(|_| xml.expect_space().map(Token::Whitespace))
683 .one(|_| parse_comment(xml))
684 .one(|_| parse_pi(xml))
685 .finish()
686 },
687
688 State::AfterDeclaration => {
689 pm.alternate()
690 .one(|pm| parse_document_type_declaration(pm, xml))
691 .one(|_| parse_element_start(xml))
692 .one(|_| xml.expect_space().map(Token::Whitespace))
693 .one(|_| parse_comment(xml))
694 .one(|_| parse_pi(xml))
695 .finish()
696 },
697
698 State::AfterElementStart(..) => {
699 pm.alternate()
700 .one(|pm| parse_attribute_start(pm, xml))
701 .one(|_| parse_element_start_close(xml))
702 .one(|_| parse_element_self_close(xml))
703 .finish()
704 },
705
706 State::AfterAttributeStart(_, quote) => {
707 pm.alternate()
708 .one(|_| parse_attribute_literal(xml, quote))
709 .one(|pm| parse_attribute_reference(pm, xml))
710 .one(|_| parse_attribute_end(xml, quote))
711 .finish()
712 },
713
714 State::Content(..) => {
715 pm.alternate()
716 .one(|_| parse_element_start(xml))
717 .one(|_| parse_element_close(xml))
718 .one(|_| parse_char_data(xml))
719 .one(|_| parse_cdata(xml))
720 .one(|pm| parse_content_reference(pm, xml))
721 .one(|_| parse_comment(xml))
722 .one(|_| parse_pi(xml))
723 .finish()
724 },
725
726 State::AfterMainElement => {
727 if xml.is_empty() {
728 return None;
729 }
730
731 pm.alternate()
732 .one(|_| parse_comment(xml))
733 .one(|_| parse_pi(xml))
734 .one(|_| xml.expect_space().map(Token::Whitespace))
735 .finish()
736 },
737 };
738
739 let (r, pt) = match pm.finish(r) {
740 peresil::Progress { status: peresil::Status::Success(t), point } => (t, point),
741 peresil::Progress { status: peresil::Status::Failure(e), point } => {
742 return Some(Err((point.offset, e)));
743 },
744 };
745
746 if pt == xml {
747 return None;
748 }
749
750 let next_state = match (self.state, r) {
751 (State::AtBeginning, Token::XmlDeclaration) |
752 (State::AtBeginning, Token::ProcessingInstruction(..)) |
753 (State::AtBeginning, Token::Comment(..)) |
754 (State::AtBeginning, Token::Whitespace(..)) => {
755 State::AfterDeclaration
756 },
757 (State::AtBeginning, Token::ElementStart(..)) => {
758 State::AfterElementStart(0)
759 },
760
761 (State::AfterDeclaration, Token::ProcessingInstruction(..)) |
762 (State::AfterDeclaration, Token::Comment(..)) |
763 (State::AfterDeclaration, Token::Whitespace(..)) => {
764 State::AfterDeclaration
765 },
766 (State::AfterDeclaration, Token::DocumentTypeDeclaration) => {
767 State::AfterDeclaration
768 },
769 (State::AfterDeclaration, Token::ElementStart(..)) => {
770 State::AfterElementStart(0)
771 },
772
773 (State::AfterElementStart(d), Token::AttributeStart(_, q)) => {
774 State::AfterAttributeStart(d, q)
775 },
776 (State::AfterElementStart(d), Token::ElementStartClose) => {
777 State::Content(d)
778 },
779 (State::AfterElementStart(0), Token::ElementSelfClose) => {
780 State::AfterMainElement
781 },
782 (State::AfterElementStart(d), Token::ElementSelfClose) => {
783 State::Content(d - 1)
784 },
785
786 (State::AfterAttributeStart(d, q), Token::LiteralAttributeValue(..)) |
787 (State::AfterAttributeStart(d, q), Token::ReferenceAttributeValue(..)) => {
788 State::AfterAttributeStart(d, q)
789 },
790 (State::AfterAttributeStart(d, _), Token::AttributeEnd) => {
791 State::AfterElementStart(d)
792 },
793
794 (State::Content(d), Token::CharData(..)) |
795 (State::Content(d), Token::CData(..)) |
796 (State::Content(d), Token::ContentReference(..)) |
797 (State::Content(d), Token::Comment(..)) |
798 (State::Content(d), Token::ProcessingInstruction(..)) => {
799 State::Content(d)
800 },
801 (State::Content(d), Token::ElementStart(..)) => {
802 State::AfterElementStart(d + 1)
803 }
804 (State::Content(0), Token::ElementClose(..)) => {
805 State::AfterMainElement
806 }
807 (State::Content(d), Token::ElementClose(..)) => {
808 State::Content(d - 1)
809 }
810
811 (State::AfterMainElement, Token::Comment(..)) |
812 (State::AfterMainElement, Token::ProcessingInstruction(..)) |
813 (State::AfterMainElement, Token::Whitespace(..)) => {
814 State::AfterMainElement
815 }
816
817 (s, t) => {
818 unreachable!("Transitioning from {:?} to {:?} is impossible", s, t);
819 },
820 };
821
822 self.state = next_state;
823 self.xml = pt;
824
825 Some(Ok(r))
826 }
827}
828
829struct DomBuilder<'d> {
830 doc: dom::Document<'d>,
831 elements: Vec<dom::Element<'d>>,
832 element_names: Vec<Span<PrefixedName<'d>>>,
833 attributes: Vec<DeferredAttribute<'d>>,
834 seen_top_element: bool,
835}
836
837impl<'d> DomBuilder<'d> {
838 fn new(doc: dom::Document<'d>) -> DomBuilder<'d> {
839 DomBuilder {
840 doc: doc,
841 elements: vec![],
842 element_names: Vec::new(),
843 attributes: Vec::new(),
844 seen_top_element: false,
845 }
846 }
847
848 fn append_to_either<T>(&self, child: T)
849 where T: Into<dom::ChildOfRoot<'d>>
850 {
851 match self.elements.last() {
852 None => self.doc.root().append_child(child),
853 Some(parent) => parent.append_child(child.into()),
854 }
855 }
856
857 fn default_namespace_uri(&self) -> Option<&str> {
858 self.elements.last().and_then(|e| e.recursive_default_namespace_uri())
859 }
860
861 fn namespace_uri_for_prefix(&self, prefix: &str) -> Option<&str> {
862 self.elements.last().and_then(|e| e.namespace_uri_for_prefix(prefix))
863 }
864
865 fn finish_opening_tag(&mut self) -> DomBuilderResult<()> {
866 let deferred_element = self.element_names.last().expect("Unknown element name");
867 let attributes = DeferredAttributes::new(replace(&mut self.attributes, Vec::new()));
868
869 try!(attributes.check_duplicates());
870 let default_namespace = try!(attributes.default_namespace());
871
872 let mut new_prefix_mappings = HashMap::new();
873 for ns in attributes.namespaces() {
874 let value = try!(AttributeValueBuilder::convert(&ns.values));
875
876 if value.is_empty() {
877 return Err(ns.name.map(|_| SpecificError::EmptyNamespace));
878 }
879
880 new_prefix_mappings.insert(ns.name.value.local_part, value);
881 }
882 let new_prefix_mappings = new_prefix_mappings;
883
884 let element_name = &deferred_element.value;
885
886 let element = if let Some(prefix) = element_name.prefix {
887 let ns_uri = new_prefix_mappings.get(prefix).map(|p| &p[..]);
888 let ns_uri = ns_uri.or_else(|| self.namespace_uri_for_prefix(prefix));
889
890 if let Some(ns_uri) = ns_uri {
891 let element = self.doc.create_element((ns_uri, element_name.local_part));
892 element.set_preferred_prefix(Some(prefix));
893 element
894 } else {
895 return Err(deferred_element.map(|_| SpecificError::UnknownNamespacePrefix));
896 }
897 } else if let Some(ns_uri) = default_namespace {
898 if ns_uri.is_empty() {
899 let element = self.doc.create_element(element_name.local_part);
900 element.set_default_namespace_uri(None);
901 element
902 } else {
903 let element = self.doc.create_element((&ns_uri[..], element_name.local_part));
904 element.set_default_namespace_uri(Some(&ns_uri));
905 element
906 }
907 } else {
908 let ns_uri = self.default_namespace_uri();
909 let name = QName::with_namespace_uri(ns_uri, element_name.local_part);
910 self.doc.create_element(name)
911 };
912
913 for (prefix, ns_uri) in &new_prefix_mappings {
914 element.register_prefix(*prefix, ns_uri);
915 }
916
917 if !self.seen_top_element {
918 self.seen_top_element = true;
919 element.register_prefix(::XML_NS_PREFIX, ::XML_NS_URI);
920 }
921
922 self.append_to_either(element);
923 self.elements.push(element);
924
925 let mut builder = AttributeValueBuilder::new();
926
927 for attribute in attributes.attributes() {
928 let name = &attribute.name.value;
929
930 builder.clear();
931 try!(builder.ingest(&attribute.values));
932
933 if let Some(prefix) = name.prefix {
934 let ns_uri = new_prefix_mappings.get(prefix).map(|p| &p[..]);
935 let ns_uri = ns_uri.or_else(|| self.namespace_uri_for_prefix(prefix));
936
937 if let Some(ns_uri) = ns_uri {
938 let attr = element.set_attribute_value((ns_uri, name.local_part), &builder);
939 attr.set_preferred_prefix(Some(prefix));
940 } else {
941 return Err(attribute.name.map(|_| SpecificError::UnknownNamespacePrefix))
942 }
943 } else {
944 element.set_attribute_value(name.local_part, &builder);
945 }
946 }
947
948 Ok(())
949 }
950
951 fn add_attribute_value(&mut self, v: AttributeValue<'d>) {
952 let a = self.attributes.last_mut().expect("Cannot add attribute value without an attribute");
953 a.values.push(v);
954 }
955
956 fn add_text_data(&self, text: &str) {
957 let e = self.elements.last().expect("Cannot add text node without a parent");
958 let t = self.doc.create_text(text);
959 e.append_child(t);
960 }
961
962 fn has_unclosed_elements(&self) -> bool {
963 !self.elements.is_empty()
964 }
965
966 fn consume(&mut self, token: Token<'d>) -> DomBuilderResult<()> {
967 use self::Token::*;
968
969 match token {
970 XmlDeclaration => {},
971
972 DocumentTypeDeclaration => {},
973
974 ElementStart(n) => {
975 self.element_names.push(n);
976 },
977
978 ElementStartClose => {
979 try!(self.finish_opening_tag());
980 },
981
982 ElementSelfClose => {
983 try!(self.finish_opening_tag());
984
985 self.element_names.pop();
986 self.elements.pop();
987 },
988
989 ElementClose(n) => {
990 let open_name = self.element_names.pop().expect("No open element");
991 self.elements.pop();
992
993 if n.value != open_name.value {
994 return Err(n.map(|_| SpecificError::MismatchedElementEndName));
995 }
996 },
997
998 AttributeStart(n, _) => {
999 let attr = DeferredAttribute { name: n, values: Vec::new() };
1000 self.attributes.push(attr);
1001 },
1002
1003 LiteralAttributeValue(v) => {
1004 self.add_attribute_value(AttributeValue::LiteralAttributeValue(v));
1005 },
1006
1007 ReferenceAttributeValue(v) => {
1008 self.add_attribute_value(AttributeValue::ReferenceAttributeValue(v));
1009 },
1010
1011 AttributeEnd => {},
1012
1013 Whitespace(..) => {},
1014
1015 CharData(t) | CData(t) => {
1016 self.add_text_data(t)
1017 },
1018
1019 ContentReference(t) => {
1020 try!(decode_reference(t, |s| self.add_text_data(s)));
1021 },
1022
1023 Comment(c) => {
1024 let c = self.doc.create_comment(c);
1025 self.append_to_either(c);
1026 },
1027
1028 ProcessingInstruction(t, v) => {
1029 let pi = self.doc.create_processing_instruction(t, v);
1030 self.append_to_either(pi);
1031 },
1032 };
1033
1034 Ok(())
1035 }
1036}
1037
1038#[derive(Debug, PartialEq, Eq)]
1039pub struct Error {
1040 location: usize,
1041 errors: BTreeSet<SpecificError>,
1042}
1043
1044impl Error {
1045 fn new(location: usize, error: SpecificError) -> Self {
1046 let mut errors = BTreeSet::new();
1047 errors.insert(error);
1048 Error { location, errors }
1049 }
1050
1051 pub fn location(&self) -> usize { self.location }
1052}
1053
1054impl From<(usize, Vec<SpecificError>)> for Error {
1055 fn from(other: (usize, Vec<SpecificError>)) -> Self {
1056 let (location, errors) = other;
1057 let errors = errors.into_iter().collect();
1058 Error { location, errors }
1059 }
1060}
1061
1062impl From<Span<SpecificError>> for Error {
1063 fn from(other: Span<SpecificError>) -> Self {
1064 Self::new(other.offset, other.value)
1065 }
1066}
1067
1068impl fmt::Display for Error {
1069 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1070 write!(f, "XML parsing error at {}: {:?}", self.location, self.errors)
1071 }
1072}
1073
1074impl error::Error for Error {
1075 fn description(&self) -> &str {
1076 "Unable to parse XML"
1077 }
1078}
1079
1080pub fn parse(xml: &str) -> Result<super::Package, Error> {
1083 let parser = PullParser::new(xml);
1084 let package = super::Package::new();
1085
1086 {
1087 let doc = package.as_document();
1088 let mut builder = DomBuilder::new(doc);
1089
1090 for token in parser {
1091 let token = try!(token);
1092 try!(builder.consume(token));
1093 }
1094
1095 if builder.has_unclosed_elements() {
1096 return Err(Error::new(xml.len(), SpecificError::UnclosedElement));
1097 }
1098 }
1099
1100 Ok(package)
1101}
1102
1103type DomBuilderResult<T> = Result<T, Span<SpecificError>>;
1104
1105fn decode_reference<F>(ref_data: Reference, cb: F) -> DomBuilderResult<()>
1106 where F: FnOnce(&str)
1107{
1108 match ref_data {
1109 DecimalCharReference(span) => {
1110 u32::from_str_radix(span.value, 10).ok()
1111 .and_then(char::from_u32)
1112 .ok_or(span.map(|_| SpecificError::InvalidDecimalReference))
1113 .and_then(|c| {
1114 let s: String = iter::repeat(c).take(1).collect();
1115 cb(&s);
1116 Ok(())
1117 })
1118 },
1119 HexCharReference(span) => {
1120 u32::from_str_radix(span.value, 16).ok()
1121 .and_then(char::from_u32)
1122 .ok_or(span.map(|_| SpecificError::InvalidHexReference))
1123 .and_then(|c| {
1124 let s: String = iter::repeat(c).take(1).collect();
1125 cb(&s);
1126 Ok(())
1127 })
1128 },
1129 EntityReference(span) => {
1130 let s = match span.value {
1131 "amp" => "&",
1132 "lt" => "<",
1133 "gt" => ">",
1134 "apos" => "'",
1135 "quot" => "\"",
1136 _ => return Err(span.map(|_| SpecificError::UnknownNamedReference)),
1137 };
1138 cb(s);
1139 Ok(())
1140 }
1141 }
1142}
1143
1144#[derive(Debug,Copy,Clone)]
1145enum AttributeValue<'a> {
1146 ReferenceAttributeValue(Reference<'a>),
1147 LiteralAttributeValue(&'a str),
1148}
1149
1150struct AttributeValueBuilder {
1151 value: String,
1152}
1153
1154impl AttributeValueBuilder {
1155 fn convert(values: &[AttributeValue]) -> DomBuilderResult<String> {
1156 let mut builder = AttributeValueBuilder::new();
1157 try!(builder.ingest(values));
1158 Ok(builder.implode())
1159 }
1160
1161 fn new() -> AttributeValueBuilder {
1162 AttributeValueBuilder {
1163 value: String::new(),
1164 }
1165 }
1166
1167 fn ingest(&mut self, values: &[AttributeValue]) -> DomBuilderResult<()> {
1168 use self::AttributeValue::*;
1169
1170 for value in values.iter() {
1171 match *value {
1172 LiteralAttributeValue(v) => self.value.push_str(v),
1173 ReferenceAttributeValue(r) => try!(decode_reference(r, |s| self.value.push_str(s))),
1174 }
1175 }
1176
1177 Ok(())
1178 }
1179
1180 fn clear(&mut self) {
1181 self.value.clear();
1182 }
1183
1184 fn implode(self) -> String {
1185 self.value
1186 }
1187}
1188
1189impl Deref for AttributeValueBuilder {
1190 type Target = str;
1191
1192 fn deref(&self) -> &str {
1193 &self.value
1194 }
1195}
1196
1197#[derive(Debug)]
1198struct DeferredAttribute<'d> {
1199 name: Span<PrefixedName<'d>>,
1200 values: Vec<AttributeValue<'d>>,
1201}
1202
1203struct DeferredAttributes<'a> {
1204 attributes: Vec<DeferredAttribute<'a>>,
1205 namespaces: Vec<DeferredAttribute<'a>>,
1206 default_namespaces: Vec<DeferredAttribute<'a>>,
1207}
1208
1209impl<'a> DeferredAttributes<'a> {
1210 fn new(attributes: Vec<DeferredAttribute<'a>>) -> DeferredAttributes<'a> {
1211 let (mut namespaces, attributes): (Vec<_>, Vec<_>) =
1212 attributes.into_iter().partition(|attr| attr.name.value.prefix == Some("xmlns"));
1213
1214 let (mut default_namespaces, mut attributes): (Vec<_>, Vec<_>) =
1215 attributes.into_iter().partition(|attr| attr.name.value.local_part == "xmlns");
1216
1217 fn sort_by_name(a: &DeferredAttribute, b: &DeferredAttribute) -> ::std::cmp::Ordering {
1218 a.name.value.cmp(&b.name.value)
1219 }
1220
1221 attributes.sort_by(sort_by_name);
1222 namespaces.sort_by(sort_by_name);
1223 default_namespaces.sort_by(sort_by_name);
1224
1225 DeferredAttributes {
1226 attributes: attributes,
1227 namespaces: namespaces,
1228 default_namespaces: default_namespaces,
1229 }
1230 }
1231
1232 fn check_duplicates(&self) -> DomBuilderResult<()> {
1233 for w in self.attributes.windows(2) {
1234 if w[0].name.value == w[1].name.value {
1235 return Err(w[1].name.map(|_| SpecificError::DuplicateAttribute));
1236 }
1237 }
1238
1239 for w in self.namespaces.windows(2) {
1240 if w[0].name.value == w[1].name.value {
1241 return Err(w[1].name.map(|_| SpecificError::RedefinedNamespace));
1242 }
1243 }
1244
1245 Ok(())
1246 }
1247
1248 fn attributes(&self) -> &[DeferredAttribute<'a>] {
1249 &self.attributes
1250 }
1251
1252 fn namespaces(&self) -> &[DeferredAttribute<'a>] {
1253 &self.namespaces
1254 }
1255
1256 fn default_namespace(&self) -> DomBuilderResult<Option<String>> {
1257 match self.default_namespaces.len() {
1258 0 => Ok(None),
1259 1 => {
1260 let ns = &self.default_namespaces[0];
1261 let value = try!(AttributeValueBuilder::convert(&ns.values));
1262 Ok(Some(value))
1263 },
1264 _ => {
1265 let last_namespace = self.default_namespaces.last().unwrap();
1266 Err(last_namespace.name.map(|_| SpecificError::RedefinedDefaultNamespace))
1267 },
1268 }
1269 }
1270}
1271
1272#[cfg(test)]
1273mod test {
1274 use super::*;
1275 use ::{dom, Package, QName};
1276
1277 macro_rules! assert_qname_eq(
1278 ($l:expr, $r:expr) => (assert_eq!(Into::<QName>::into($l), $r.into()));
1279 );
1280
1281 fn full_parse(xml: &str) -> Result<Package, Error> {
1282 super::parse(xml)
1283 }
1284
1285 fn quick_parse(xml: &str) -> Package {
1286 full_parse(xml).expect("Failed to parse the XML string")
1287 }
1288
1289 fn top<'d>(doc: &'d dom::Document<'d>) -> dom::Element<'d> {
1290 doc.root().children()[0].element().unwrap()
1291 }
1292
1293 #[test]
1294 fn a_document_with_a_prolog() {
1295 let package = quick_parse("<?xml version='1.0' ?><hello />");
1296 let doc = package.as_document();
1297 let top = top(&doc);
1298
1299 assert_qname_eq!(top.name(), "hello");
1300 }
1301
1302 #[test]
1303 fn a_document_with_a_prolog_with_double_quotes() {
1304 let package = quick_parse("<?xml version=\"1.0\" ?><hello />");
1305 let doc = package.as_document();
1306 let top = top(&doc);
1307
1308 assert_qname_eq!(top.name(), "hello");
1309 }
1310
1311 #[test]
1312 fn a_prolog_with_an_encoding() {
1313 let package = quick_parse("<?xml version='1.0' encoding='UTF-8' ?><hello />");
1314 let doc = package.as_document();
1315 let top = top(&doc);
1316
1317 assert_qname_eq!(top.name(), "hello");
1318 }
1319
1320 #[test]
1321 fn a_non_standalone_prolog() {
1322 let package = quick_parse("<?xml version='1.0' standalone='no'?><hello/>");
1323 let doc = package.as_document();
1324 let top = top(&doc);
1325
1326 assert_qname_eq!(top.name(), "hello");
1327 }
1328
1329 #[test]
1330 fn a_complete_prolog() {
1331 let package = quick_parse("<?xml version='1.0' encoding='UTF-8' standalone='yes'?><hello/>");
1332 let doc = package.as_document();
1333 let top = top(&doc);
1334
1335 assert_qname_eq!(top.name(), "hello");
1336 }
1337
1338 #[test]
1339 fn a_prolog_with_a_doc_type_declaration_external_id() {
1340 let package = quick_parse(r#"<?xml version='1.0'?>
1341 <!DOCTYPE doc SYSTEM "http://example.com/doc.dtd">
1342 <hello/>"#);
1343 let doc = package.as_document();
1344 let top = top(&doc);
1345
1346 assert_qname_eq!(top.name(), "hello");
1347 }
1348
1349 #[test]
1350 fn a_prolog_with_a_doc_type_declaration_int_subset() {
1351 let package = quick_parse(r#"<?xml version="1.0"?>
1352 <!DOCTYPE note [
1353 <!ELEMENT note (to,from,heading,body)>
1354 <!ELEMENT to (#PCDATA)>
1355 <!ELEMENT from (#PCDATA)>
1356 <!ELEMENT heading (#PCDATA)>
1357 <!ELEMENT body (#PCDATA)>
1358 ]>
1359 <note>
1360 <to>Tove</to>
1361 <from>Jani</from>
1362 <heading>Reminder</heading>
1363 <body>Don't forget me this weekend</body>
1364 </note>
1365 "#);
1366 let doc = package.as_document();
1367 let top = top(&doc);
1368
1369 assert_qname_eq!(top.name(), "note");
1370 }
1371
1372 #[test]
1373 fn a_prolog_with_a_doc_type_declaration_int_subset_trailing_ws() {
1374 let package = quick_parse(r#"<?xml version="1.0"?>
1375 <!DOCTYPE note
1376 [
1377 <!ELEMENT note (to,from,heading,body)>
1378 <!ELEMENT to (#PCDATA)>
1379 <!ELEMENT from (#PCDATA)>
1380 <!ELEMENT heading (#PCDATA)>
1381 <!ELEMENT body (#PCDATA)>
1382 ]
1383
1384 >
1385 <note>
1386 <to>Tove</to>
1387 <from>Jani</from>
1388 <heading>Reminder</heading>
1389 <body>Don't forget me this weekend</body>
1390 </note>
1391 "#);
1392 let doc = package.as_document();
1393 let top = top(&doc);
1394
1395 assert_qname_eq!(top.name(), "note");
1396 }
1397
1398 #[test]
1399 fn a_prolog_with_a_doc_type_declaration_zero_def() {
1400 let package = quick_parse("<?xml version='1.0'?>
1401 <!DOCTYPE doc>
1402 <hello/>");
1403 let doc = package.as_document();
1404 let top = top(&doc);
1405
1406 assert_qname_eq!(top.name(), "hello");
1407 }
1408
1409 #[test]
1410 fn a_prolog_with_a_doc_type_declaration_zero_def_trailing_ws() {
1411 let package = quick_parse("<?xml version='1.0'?>
1412 <!DOCTYPE doc >
1413 <hello/>");
1414 let doc = package.as_document();
1415 let top = top(&doc);
1416
1417 assert_qname_eq!(top.name(), "hello");
1418 }
1419
1420 #[test]
1421 fn a_prolog_with_a_doc_type_declaration_both_int_subset_and_external_id() {
1422 let package = quick_parse(r#"<?xml version='1.0'?>
1423 <!DOCTYPE doc SYSTEM "http://example.com/doc.dtd" [
1424 <!ELEMENT hello (#PCDATA)>
1425 ]>
1426 <hello/>"#);
1427 let doc = package.as_document();
1428 let top = top(&doc);
1429
1430 assert_qname_eq!(top.name(), "hello");
1431 }
1432
1433 #[test]
1434 fn a_prolog_with_a_doc_type_declaration_both_int_subset_and_external_id_trailing_ws() {
1435 let package = quick_parse(r#"<?xml version='1.0'?>
1436 <!DOCTYPE doc SYSTEM "http://example.com/doc.dtd" [
1437 <!ELEMENT hello (#PCDATA)>
1438 ] >
1439 <hello/>"#);
1440 let doc = package.as_document();
1441 let top = top(&doc);
1442
1443 assert_qname_eq!(top.name(), "hello");
1444 }
1445
1446 #[test]
1447 fn a_document_with_a_single_element() {
1448 let package = quick_parse("<hello />");
1449 let doc = package.as_document();
1450 let top = top(&doc);
1451
1452 assert_qname_eq!(top.name(), "hello");
1453 }
1454
1455 #[test]
1456 fn an_element_with_a_namespace() {
1457 let package = quick_parse("<ns:hello xmlns:ns='namespace'/>");
1458 let doc = package.as_document();
1459 let top = top(&doc);
1460
1461 assert_eq!(top.preferred_prefix(), Some("ns"));
1462 assert_qname_eq!(("namespace", "hello"), top.name());
1463 }
1464
1465 #[test]
1466 fn an_element_with_a_default_namespace() {
1467 let package = quick_parse("<hello xmlns='namespace'/>");
1468 let doc = package.as_document();
1469 let top = top(&doc);
1470
1471 assert_eq!(top.default_namespace_uri(), Some("namespace"));
1472 assert_qname_eq!(("namespace", "hello"), top.name());
1473 }
1474
1475 #[test]
1476 fn an_element_with_an_attribute() {
1477 let package = quick_parse("<hello scope='world'/>");
1478 let doc = package.as_document();
1479 let top = top(&doc);
1480
1481 assert_eq!(top.attribute_value("scope"), Some("world"));
1482 }
1483
1484 #[test]
1485 fn an_element_with_an_attribute_using_double_quotes() {
1486 let package = quick_parse("<hello scope=\"world\"/>");
1487 let doc = package.as_document();
1488 let top = top(&doc);
1489
1490 assert_eq!(top.attribute_value("scope"), Some("world"));
1491 }
1492
1493 #[test]
1494 fn an_element_with_multiple_attributes() {
1495 let package = quick_parse("<hello scope='world' happy='true'/>");
1496 let doc = package.as_document();
1497 let top = top(&doc);
1498
1499 assert_eq!(top.attribute_value("scope"), Some("world"));
1500 assert_eq!(top.attribute_value("happy"), Some("true"));
1501 }
1502
1503 #[test]
1504 fn an_attribute_with_a_namespace() {
1505 let package = quick_parse("<hello ns:a='b' xmlns:ns='namespace'/>");
1506 let doc = package.as_document();
1507 let top = top(&doc);
1508
1509 let attr = top.attribute(("namespace", "a")).unwrap();
1510
1511 assert_eq!(attr.preferred_prefix(), Some("ns"));
1512 assert_eq!(attr.value(), "b");
1513 }
1514
1515 #[test]
1516 fn an_attribute_with_xml_space_preserve() {
1517 let package = quick_parse("<hello xml:space='preserve'> <a/> </hello>");
1518 let doc = package.as_document();
1519 let top = top(&doc);
1520
1521 assert_eq!(top.attribute((::XML_NS_URI, "space")).unwrap().value(), "preserve");
1522
1523 let children = top.children();
1524 assert_eq!(children.len(), 3);
1525 assert_eq!(children[0].text().unwrap().text(), " ");
1526 assert_qname_eq!(children[1].element().unwrap().name(), "a");
1527 assert_eq!(children[2].text().unwrap().text(), " ");
1528 }
1529
1530 #[test]
1531 fn an_attribute_with_references() {
1532 let package = quick_parse("<log msg='I <3 math' />");
1533 let doc = package.as_document();
1534 let top = top(&doc);
1535
1536 assert_eq!(top.attribute_value("msg"), Some("I <3 math"));
1537 }
1538
1539 #[test]
1540 fn an_element_that_is_not_self_closing() {
1541 let package = quick_parse("<hello></hello>");
1542 let doc = package.as_document();
1543 let top = top(&doc);
1544
1545 assert_qname_eq!(top.name(), "hello");
1546 }
1547
1548 #[test]
1549 fn nested_elements() {
1550 let package = quick_parse("<hello><world/></hello>");
1551 let doc = package.as_document();
1552 let hello = top(&doc);
1553 let world = hello.children()[0].element().unwrap();
1554
1555 assert_qname_eq!(world.name(), "world");
1556 }
1557
1558 #[test]
1559 fn multiply_nested_elements() {
1560 let package = quick_parse("<hello><awesome><world/></awesome></hello>");
1561 let doc = package.as_document();
1562 let hello = top(&doc);
1563 let awesome = hello.children()[0].element().unwrap();
1564 let world = awesome.children()[0].element().unwrap();
1565
1566 assert_qname_eq!(world.name(), "world");
1567 }
1568
1569 #[test]
1570 fn nested_elements_with_namespaces() {
1571 let package = quick_parse("<ns1:hello xmlns:ns1='outer'><ns2:world xmlns:ns2='inner'/></ns1:hello>");
1572 let doc = package.as_document();
1573 let hello = top(&doc);
1574 let world = hello.children()[0].element().unwrap();
1575
1576 assert_qname_eq!(world.name(), ("inner", "world"));
1577 }
1578
1579 #[test]
1580 fn nested_elements_with_inherited_namespaces() {
1581 let package = quick_parse("<ns1:hello xmlns:ns1='outer'><ns1:world/></ns1:hello>");
1582 let doc = package.as_document();
1583 let hello = top(&doc);
1584 let world = hello.children()[0].element().unwrap();
1585
1586 assert_eq!(world.preferred_prefix(), Some("ns1"));
1587 assert_qname_eq!(world.name(), ("outer", "world"));
1588 }
1589
1590 #[test]
1591 fn nested_elements_with_inherited_default_namespace() {
1592 let package = quick_parse("<hello xmlns='outer'><world/></hello>");
1593 let doc = package.as_document();
1594 let hello = top(&doc);
1595 let world = hello.children()[0].element().unwrap();
1596
1597 assert_qname_eq!(world.name(), ("outer", "world"));
1598 }
1599
1600 #[test]
1601 fn nested_elements_with_reset_default_namespace() {
1602 let package = quick_parse("<hello xmlns='outer'><world xmlns=''/></hello>");
1603 let doc = package.as_document();
1604 let hello = top(&doc);
1605 let world = hello.children()[0].element().unwrap();
1606
1607 assert_qname_eq!(world.name(), "world");
1608 }
1609
1610 #[test]
1611 fn nested_elements_with_attributes() {
1612 let package = quick_parse("<hello><world name='Earth'/></hello>");
1613 let doc = package.as_document();
1614 let hello = top(&doc);
1615 let world = hello.children()[0].element().unwrap();
1616
1617 assert_eq!(world.attribute_value("name"), Some("Earth"));
1618 }
1619
1620 #[test]
1621 fn nested_elements_with_attributes_with_inherited_namespaces() {
1622 let package = quick_parse("<hello xmlns:ns1='outer'><world ns1:name='Earth'/></hello>");
1623 let doc = package.as_document();
1624 let hello = top(&doc);
1625 let world = hello.children()[0].element().unwrap();
1626
1627 let attr = world.attribute(("outer", "name")).unwrap();
1628
1629 assert_eq!(attr.preferred_prefix(), Some("ns1"));
1630 assert_eq!(attr.value(), "Earth");
1631 }
1632
1633 #[test]
1634 fn element_with_text() {
1635 let package = quick_parse("<hello>world</hello>");
1636 let doc = package.as_document();
1637 let hello = top(&doc);
1638 let text = hello.children()[0].text().unwrap();
1639
1640 assert_eq!(text.text(), "world");
1641 }
1642
1643 #[test]
1644 fn element_with_cdata() {
1645 let package = quick_parse("<words><![CDATA[I have & and < !]]></words>");
1646 let doc = package.as_document();
1647 let words = top(&doc);
1648 let text = words.children()[0].text().unwrap();
1649
1650 assert_eq!(text.text(), "I have & and < !");
1651 }
1652
1653 #[test]
1654 fn element_with_comment() {
1655 let package = quick_parse("<hello><!-- A comment --></hello>");
1656 let doc = package.as_document();
1657 let words = top(&doc);
1658 let comment = words.children()[0].comment().unwrap();
1659
1660 assert_eq!(comment.text(), " A comment ");
1661 }
1662
1663 #[test]
1664 fn comment_before_top_element() {
1665 let package = quick_parse("<!-- A comment --><hello />");
1666 let doc = package.as_document();
1667 let comment = doc.root().children()[0].comment().unwrap();
1668
1669 assert_eq!(comment.text(), " A comment ");
1670 }
1671
1672 #[test]
1673 fn multiple_comments_before_top_element() {
1674 let xml = r"
1675<!--Comment 1-->
1676<!--Comment 2-->
1677<hello />";
1678 let package = quick_parse(xml);
1679 let doc = package.as_document();
1680 let comment1 = doc.root().children()[0].comment().unwrap();
1681 let comment2 = doc.root().children()[1].comment().unwrap();
1682
1683 assert_eq!(comment1.text(), "Comment 1");
1684 assert_eq!(comment2.text(), "Comment 2");
1685 }
1686
1687 #[test]
1688 fn multiple_comments_after_top_element() {
1689 let xml = r"
1690<hello />
1691<!--Comment 1-->
1692<!--Comment 2-->";
1693 let package = quick_parse(xml);
1694 let doc = package.as_document();
1695 let comment1 = doc.root().children()[1].comment().unwrap();
1696 let comment2 = doc.root().children()[2].comment().unwrap();
1697
1698 assert_eq!(comment1.text(), "Comment 1");
1699 assert_eq!(comment2.text(), "Comment 2");
1700 }
1701
1702 #[test]
1703 fn element_with_processing_instruction() {
1704 let package = quick_parse("<hello><?device?></hello>");
1705 let doc = package.as_document();
1706 let hello = top(&doc);
1707 let pi = hello.children()[0].processing_instruction().unwrap();
1708
1709 assert_eq!(pi.target(), "device");
1710 assert_eq!(pi.value(), None);
1711 }
1712
1713 #[test]
1714 fn top_level_processing_instructions() {
1715 let xml = r"
1716<?output printer?>
1717<hello />
1718<?validated?>";
1719
1720 let package = quick_parse(xml);
1721 let doc = package.as_document();
1722 let pi1 = doc.root().children()[0].processing_instruction().unwrap();
1723 let pi2 = doc.root().children()[2].processing_instruction().unwrap();
1724
1725 assert_eq!(pi1.target(), "output");
1726 assert_eq!(pi1.value(), Some("printer"));
1727
1728 assert_eq!(pi2.target(), "validated");
1729 assert_eq!(pi2.value(), None);
1730 }
1731
1732 #[test]
1733 fn element_with_decimal_char_reference() {
1734 let package = quick_parse("<math>2 > 1</math>");
1735 let doc = package.as_document();
1736 let math = top(&doc);
1737 let text1 = math.children()[0].text().unwrap();
1738 let text2 = math.children()[1].text().unwrap();
1739 let text3 = math.children()[2].text().unwrap();
1740
1741 assert_eq!(text1.text(), "2 ");
1742 assert_eq!(text2.text(), ">");
1743 assert_eq!(text3.text(), " 1");
1744 }
1745
1746 #[test]
1747 fn element_with_hexidecimal_char_reference() {
1748 let package = quick_parse("<math>1 < 2</math>");
1749 let doc = package.as_document();
1750 let math = top(&doc);
1751 let text1 = math.children()[0].text().unwrap();
1752 let text2 = math.children()[1].text().unwrap();
1753 let text3 = math.children()[2].text().unwrap();
1754
1755 assert_eq!(text1.text(), "1 ");
1756 assert_eq!(text2.text(), "<");
1757 assert_eq!(text3.text(), " 2");
1758 }
1759
1760 #[test]
1761 fn element_with_entity_reference() {
1762 let package = quick_parse("<math>I <3 math</math>");
1763 let doc = package.as_document();
1764 let math = top(&doc);
1765 let text1 = math.children()[0].text().unwrap();
1766 let text2 = math.children()[1].text().unwrap();
1767 let text3 = math.children()[2].text().unwrap();
1768
1769 assert_eq!(text1.text(), "I ");
1770 assert_eq!(text2.text(), "<");
1771 assert_eq!(text3.text(), "3 math");
1772 }
1773
1774 #[test]
1775 fn element_with_mixed_children() {
1776 let package = quick_parse("<hello>to <!--fixme--><a><![CDATA[the]]></a><?world?></hello>");
1777 let doc = package.as_document();
1778 let hello = top(&doc);
1779
1780 let text = hello.children()[0].text().unwrap();
1781 let comment = hello.children()[1].comment().unwrap();
1782 let element = hello.children()[2].element().unwrap();
1783 let pi = hello.children()[3].processing_instruction().unwrap();
1784
1785 assert_eq!(text.text(), "to ");
1786 assert_eq!(comment.text(), "fixme");
1787 assert_qname_eq!(element.name(), "a");
1788 assert_eq!(pi.target(), "world");
1789 }
1790
1791 macro_rules! assert_parse_failure {
1803 ($actual:expr, $pos:expr, $($err:expr),+) => {
1804 {
1805 let errors = vec![$($err),+];
1806 let expected = Err(Error::from(($pos, errors)));
1807 assert_eq!($actual, expected);
1808 }
1809 }
1810 }
1811
1812 #[test]
1813 fn failure_invalid_encoding() {
1814 use super::SpecificError::*;
1815
1816 let r = full_parse("<?xml version='1.0' encoding='8BIT' ?><hi/>");
1817
1818 assert_parse_failure!(r, 30, ExpectedEncoding);
1819 }
1820
1821 #[test]
1822 fn failure_invalid_standalone() {
1823 use super::SpecificError::*;
1824
1825 let r = full_parse("<?xml version='1.0' standalone='invalid'?><hello/>");
1826
1827 assert_parse_failure!(r, 32, ExpectedYesNo);
1828 }
1829
1830 #[test]
1831 fn failure_no_open_brace() {
1832 use super::SpecificError::*;
1833
1834 let r = full_parse("hi />");
1835
1836 assert_parse_failure!(r, 0, Expected("<?xml"), ExpectedComment, ExpectedProcessingInstruction, ExpectedWhitespace, ExpectedElement);
1837 }
1838
1839 #[test]
1840 fn failure_unclosed_tag() {
1841 use super::SpecificError::*;
1842
1843 let r = full_parse("<hi");
1844
1845 assert_parse_failure!(r, 3, ExpectedWhitespace, ExpectedElementSelfClosed, ExpectedElementEnd);
1846 }
1847
1848 #[test]
1849 fn failure_unexpected_space() {
1850 use super::SpecificError::*;
1851
1852 let r = full_parse("<hi / >");
1853
1854 assert_parse_failure!(r, 4, ExpectedAttribute, ExpectedElementSelfClosed, ExpectedElementEnd);
1855 }
1856
1857 #[test]
1858 fn failure_attribute_without_open_quote() {
1859 use super::SpecificError::*;
1860
1861 let r = full_parse("<hi oops=value' />");
1862
1863 assert_parse_failure!(r, 9, ExpectedOpeningQuote("\'"), ExpectedOpeningQuote("\""));
1864 }
1865
1866 #[test]
1867 fn failure_attribute_without_close_quote() {
1868 use super::SpecificError::*;
1869
1870 let r = full_parse("<hi oops='value />");
1871
1872 assert_parse_failure!(r, 18, ExpectedNamedReference, ExpectedDecimalReference, ExpectedAttributeValue, ExpectedHexReference, ExpectedClosingQuote("\'"));
1873 }
1874
1875 #[test]
1876 fn failure_unclosed_attribute_and_tag() {
1877 use super::SpecificError::*;
1878
1879 let r = full_parse("<hi oops='value");
1880
1881 assert_parse_failure!(r, 15, ExpectedNamedReference, ExpectedDecimalReference, ExpectedAttributeValue, ExpectedHexReference, ExpectedClosingQuote("\'"));
1882 }
1883
1884 #[test]
1885 fn failure_nested_unclosed_tag() {
1886 use super::SpecificError::*;
1887
1888 let r = full_parse("<hi><oops</hi>");
1889
1890 assert_parse_failure!(r, 9, ExpectedWhitespace, ExpectedElementSelfClosed, ExpectedElementEnd);
1891 }
1892
1893 #[test]
1894 fn failure_missing_close_tag() {
1895 use super::SpecificError::*;
1896
1897 let r = full_parse("<hi>wow");
1898
1899 assert_parse_failure!(r, 7, UnclosedElement);
1900 }
1901
1902 #[test]
1903 fn failure_nested_unexpected_space() {
1904 use super::SpecificError::*;
1905
1906 let r = full_parse("<hi><oops / ></hi>");
1907
1908 assert_parse_failure!(r, 10, ExpectedAttribute, ExpectedElementSelfClosed, ExpectedElementEnd);
1909 }
1910
1911 #[test]
1912 fn failure_malformed_entity_reference() {
1913 use super::SpecificError::*;
1914
1915 let r = full_parse("<hi>Entity: &;</hi>");
1916
1917 assert_parse_failure!(r, 13, ExpectedNamedReferenceValue);
1918 }
1919
1920 #[test]
1921 fn failure_nested_malformed_entity_reference() {
1922 use super::SpecificError::*;
1923
1924 let r = full_parse("<hi><bye>Entity: &;</bye></hi>");
1925
1926 assert_parse_failure!(r, 18, ExpectedNamedReferenceValue);
1927 }
1928
1929 #[test]
1930 fn failure_nested_attribute_without_open_quote() {
1931 use super::SpecificError::*;
1932
1933 let r = full_parse("<hi><bye oops=value' /></hi>");
1934
1935 assert_parse_failure!(r, 14, ExpectedOpeningQuote("\'"), ExpectedOpeningQuote("\""));
1936 }
1937
1938 #[test]
1939 fn failure_nested_attribute_without_close_quote() {
1940 use super::SpecificError::*;
1941
1942 let r = full_parse("<hi><bye oops='value /></hi>");
1943
1944 assert_parse_failure!(r, 23, ExpectedNamedReference, ExpectedDecimalReference, ExpectedAttributeValue, ExpectedHexReference, ExpectedClosingQuote("\'"));
1945 }
1946
1947 #[test]
1948 fn failure_nested_unclosed_attribute_and_tag() {
1949 use super::SpecificError::*;
1950
1951 let r = full_parse("<hi><bye oops='value</hi>");
1952
1953 assert_parse_failure!(r, 20, ExpectedNamedReference, ExpectedDecimalReference, ExpectedAttributeValue, ExpectedHexReference, ExpectedClosingQuote("\'"));
1954 }
1955
1956 #[test]
1957 fn failure_pi_target_as_xml() {
1958 use super::SpecificError::*;
1959
1960 let r = full_parse("<a><?xml?></a>");
1961
1962 assert_parse_failure!(r, 5, InvalidProcessingInstructionTarget);
1963 }
1964
1965 #[test]
1966 fn failure_end_tag_does_not_match() {
1967 use super::SpecificError::*;
1968
1969 let r = full_parse("<a></b>");
1970
1971 assert_parse_failure!(r, 5, MismatchedElementEndName);
1972 }
1973
1974 #[test]
1975 fn failure_invalid_decimal_reference() {
1976 use super::SpecificError::*;
1977
1978 let r = full_parse("<a>�</a>");
1979
1980 assert_parse_failure!(r, 5, InvalidDecimalReference);
1981 }
1982
1983 #[test]
1984 fn failure_invalid_hex_reference() {
1985 use super::SpecificError::*;
1986
1987 let r = full_parse("<a>�</a>");
1988
1989 assert_parse_failure!(r, 6, InvalidHexReference);
1990 }
1991
1992 #[test]
1993 fn failure_unknown_named_reference() {
1994 use super::SpecificError::*;
1995
1996 let r = full_parse("<a>&fake;</a>");
1997
1998 assert_parse_failure!(r, 4, UnknownNamedReference);
1999 }
2000
2001 #[test]
2002 fn failure_duplicate_attribute() {
2003 use super::SpecificError::*;
2004
2005 let r = full_parse("<a b='c' b='d'/>");
2006
2007 assert_parse_failure!(r, 9, DuplicateAttribute);
2008 }
2009
2010 #[test]
2011 fn failure_redefined_namespace() {
2012 use super::SpecificError::*;
2013
2014 let r = full_parse("<a xmlns:b='c' xmlns:b='d'/>");
2015
2016 assert_parse_failure!(r, 15, RedefinedNamespace);
2017 }
2018
2019 #[test]
2020 fn failure_redefined_default_namespace() {
2021 use super::SpecificError::*;
2022
2023 let r = full_parse("<a xmlns='a' xmlns='b'/>");
2024
2025 assert_parse_failure!(r, 13, RedefinedDefaultNamespace);
2026 }
2027
2028 #[test]
2029 fn failure_empty_namespace() {
2030 use super::SpecificError::*;
2031
2032 let r = full_parse("<a xmlns:b=''/>");
2033
2034 assert_parse_failure!(r, 3, EmptyNamespace);
2035 }
2036
2037 #[test]
2038 fn failure_unknown_attribute_namespace_prefix() {
2039 use super::SpecificError::*;
2040
2041 let r = full_parse("<a b:foo='a'/>");
2042
2043 assert_parse_failure!(r, 3, UnknownNamespacePrefix);
2044 }
2045
2046 #[test]
2047 fn failure_unknown_element_namespace_prefix() {
2048 use super::SpecificError::*;
2049
2050 let r = full_parse("<b:a/>");
2051
2052 assert_parse_failure!(r, 1, UnknownNamespacePrefix);
2053 }
2054
2055 #[test]
2056 fn failure_is_an_error() {
2057 fn __assert_well_behaved_error()
2058 where
2059 Error: ::std::error::Error + Send + Sync + 'static,
2060 {}
2061 }
2062}