1use std::borrow::ToOwned;
26use std::io::{self,Write};
27use std::slice;
28
29use self::Content::*;
30
31use super::QName;
32use super::str_ext::{SplitKeepingDelimiterExt,SplitType};
33
34
35use super::dom;
36use super::dom::{ChildOfElement,ChildOfRoot};
37use super::lazy_hash_map::LazyHashMap;
38
39trait WriteStr: Write {
40 fn write_str(&mut self, s: &str) -> io::Result<()> {
41 self.write_all(s.as_bytes())
42 }
43}
44
45impl<W: ?Sized> WriteStr for W where W: Write {}
46
47struct PrefixScope<'d> {
49 ns_to_prefix: LazyHashMap<&'d str, String>,
50 prefix_to_ns: LazyHashMap<String, &'d str>,
51 defined_prefixes: Vec<(String, &'d str)>,
52 default_namespace_uri: Option<&'d str>,
53}
54
55impl<'d> PrefixScope<'d> {
56 fn new() -> PrefixScope<'d> {
57 PrefixScope {
58 ns_to_prefix: LazyHashMap::new(),
59 prefix_to_ns: LazyHashMap::new(),
60 defined_prefixes: Vec::new(),
61 default_namespace_uri: None,
62 }
63 }
64
65 fn has_prefix(&self, prefix: &str) -> bool {
66 self.prefix_to_ns.contains_key(prefix)
67 }
68
69 fn has_namespace_uri(&self, namespace_uri: &str) -> bool {
70 self.ns_to_prefix.contains_key(namespace_uri)
71 }
72
73 fn prefix_is(&self, prefix: &str, namespace_uri: &str) -> bool {
74 match self.prefix_to_ns.get(prefix) {
75 Some(ns) => *ns == namespace_uri,
76 _ => false,
77 }
78 }
79
80 fn namespace_uri_for(&self, prefix: &str) -> Option<&'d str> {
81 self.prefix_to_ns.get(prefix).map(|&ns| ns)
82 }
83
84 fn prefix_for(&self, namespace_uri: &str) -> Option<&str> {
85 self.ns_to_prefix.get(namespace_uri).map(|p| &p[..])
86 }
87
88 fn add_mapping(&mut self, prefix: &str, namespace_uri: &'d str) {
89 let prefix = prefix.to_owned();
90
91 self.prefix_to_ns.insert(prefix.clone(), namespace_uri);
92 self.ns_to_prefix.insert(namespace_uri, prefix);
93 }
94
95 fn define_prefix(&mut self, prefix: String, namespace_uri: &'d str) {
96 self.defined_prefixes.push((prefix, namespace_uri));
97 }
98}
99
100enum NamespaceType<'a> {
101 Default,
102 Prefix(&'a str),
103 Unknown,
104}
105
106struct PrefixMapping<'d> {
107 scopes: Vec<PrefixScope<'d>>,
108 generated_prefix_count: usize,
109}
110
111impl<'d> PrefixMapping<'d> {
112 fn new() -> PrefixMapping<'d> {
113 PrefixMapping {
114 scopes: vec![PrefixScope::new()],
115 generated_prefix_count: 0,
116 }
117 }
118
119 fn push_scope(&mut self) {
120 self.scopes.push(PrefixScope::new());
121 }
122
123 fn pop_scope(&mut self) {
124 self.scopes.pop();
125 }
126
127 fn active_default_namespace_uri(&self) -> Option<&'d str> {
128 self.scopes.iter().rev().filter_map(|s| s.default_namespace_uri).next()
129 }
130
131 fn active_namespace_uri_for_prefix(&self, prefix: &str) -> Option<&'d str> {
132 self.scopes.iter().rev().filter_map(|s| s.namespace_uri_for(prefix)).next()
133 }
134
135 fn default_namespace_uri_in_current_scope(&self) -> Option<&'d str> {
136 self.scopes.last().unwrap().default_namespace_uri
137 }
138
139 fn prefixes_in_current_scope(&self) -> slice::Iter<(String, &'d str)> {
140 self.scopes.last().unwrap().defined_prefixes.iter()
141 }
142
143 fn populate_scope(&mut self, element: &dom::Element<'d>, attributes: &[dom::Attribute<'d>]) {
144 self.scopes.last_mut().unwrap().default_namespace_uri = element.default_namespace_uri();
145
146 if let Some(prefix) = element.preferred_prefix() {
147 let name = element.name();
148 if let Some(uri) = name.namespace_uri {
149 self.set_prefix(prefix, uri);
150 }
151 }
152
153 for attribute in attributes.iter() {
154 if let Some(prefix) = attribute.preferred_prefix() {
155 let name = attribute.name();
156 if let Some(uri) = name.namespace_uri {
157 self.set_prefix(prefix, uri);
158 }
159 }
160 }
161
162 let name = element.name();
163 if let Some(uri) = name.namespace_uri {
164 self.generate_prefix(uri);
165 }
166
167 for attribute in attributes.iter() {
168 let name = attribute.name();
169 if let Some(uri) = name.namespace_uri {
170 self.generate_prefix(uri);
171 }
172 }
173 }
174
175 fn set_prefix(&mut self, prefix: &str, namespace_uri: &'d str) {
176 let idx_of_last = self.scopes.len().saturating_sub(1);
177 let (parents, current_scope) = self.scopes.split_at_mut(idx_of_last);
178 let current_scope = &mut current_scope[0];
179
180 if current_scope.has_prefix(prefix) {
182 return;
183 }
184
185 current_scope.add_mapping(prefix, namespace_uri);
187
188 for parent_scope in parents.iter().rev() {
189 if parent_scope.prefix_is(prefix, namespace_uri) {
190 return;
193 }
194 }
195
196 current_scope.define_prefix(prefix.to_owned(), namespace_uri);
198 }
199
200 fn generate_prefix(&mut self, namespace_uri: &'d str) {
201 if Some(namespace_uri) == self.active_default_namespace_uri() {
202 return;
204 }
205
206 let idx_of_last = self.scopes.len().saturating_sub(1);
207 let (parents, current_scope) = self.scopes.split_at_mut(idx_of_last);
208 let current_scope = &mut current_scope[0];
209
210 if current_scope.has_namespace_uri(namespace_uri) {
211 return;
213 }
214
215 for parent_scope in parents.iter().rev() {
217 if let Some(prefix) = parent_scope.prefix_for(namespace_uri) {
218 current_scope.add_mapping(prefix, namespace_uri);
221 return;
222 }
223 }
224
225 loop {
226 let prefix = format!("autons{}", self.generated_prefix_count);
227 self.generated_prefix_count += 1;
228
229 if ! current_scope.has_prefix(&prefix) {
230 current_scope.add_mapping(&prefix, namespace_uri);
231 current_scope.define_prefix(prefix, namespace_uri);
232 break;
233 }
234 }
235 }
236
237 fn namespace_type<'a>(&'a self,
238 preferred_prefix: Option<&'a str>,
239 namespace_uri: &str,
240 ignore_default: bool)
241 -> NamespaceType<'a>
242 {
243 if !ignore_default && Some(namespace_uri) == self.active_default_namespace_uri() {
244 return NamespaceType::Default;
245 }
246
247 if let Some(prefix) = preferred_prefix {
248 if Some(namespace_uri) == self.active_namespace_uri_for_prefix(prefix) {
249 return NamespaceType::Prefix(prefix);
250 }
251 }
252
253 for scope in self.scopes.iter().rev() {
254 if let Some(prefix) = scope.prefix_for(namespace_uri) {
255 return NamespaceType::Prefix(prefix);
256 }
257 }
258
259 NamespaceType::Unknown
260 }
261}
262
263enum Content<'d> {
264 Element(dom::Element<'d>),
265 ElementEnd(dom::Element<'d>),
266 Text(dom::Text<'d>),
267 Comment(dom::Comment<'d>),
268 ProcessingInstruction(dom::ProcessingInstruction<'d>),
269}
270
271pub struct Writer {
295 single_quotes: bool,
296 write_encoding: bool,
297}
298
299impl Default for Writer {
300 fn default() -> Self {
301 Self {
302 single_quotes: true,
303 write_encoding: false,
304 }
305 }
306}
307
308impl Writer {
309 pub fn new() -> Self {
311 Self::default()
312 }
313
314 pub fn set_single_quotes(mut self, single_quotes: bool) -> Self {
316 self.single_quotes = single_quotes;
317 self
318 }
319
320 pub fn set_write_encoding(mut self, write_encoding: bool) -> Self {
322 self.write_encoding = write_encoding;
323 self
324 }
325
326 fn quote_char(&self) -> &'static str {
327 match self.single_quotes {
328 true => "'",
329 false => "\"",
330 }
331 }
332}
333
334impl Writer {
335 fn format_qname<'d, W: ?Sized>(&self,
336 q: QName<'d>,
337 mapping: &mut PrefixMapping<'d>,
338 preferred_prefix: Option<&str>,
339 ignore_default: bool,
340 writer: &mut W)
341 -> io::Result<()>
342 where W: Write
343 {
344 if let Some(namespace_uri) = q.namespace_uri {
347 match mapping.namespace_type(preferred_prefix, namespace_uri, ignore_default) {
348 NamespaceType::Default => {
349 },
351 NamespaceType::Prefix(prefix) => {
352 try!(writer.write_str(prefix));
353 try!(writer.write_str(":"));
354 },
355 NamespaceType::Unknown => {
356 panic!("No namespace prefix available for {}", namespace_uri);
357 },
358 }
359 }
360 writer.write_str(q.local_part)
361 }
362
363 fn format_attribute_value<W: ?Sized>(&self, value: &str, writer: &mut W) -> io::Result<()>
364 where W: Write
365 {
366 for item in value.split_keeping_delimiter(|c| c == '<' || c == '>' || c == '&' || c == '\'' || c == '"') {
367 match item {
368 SplitType::Match(t) => try!(writer.write_str(t)),
369 SplitType::Delimiter("<") => try!(writer.write_str("<")),
370 SplitType::Delimiter(">") => try!(writer.write_str(">")),
371 SplitType::Delimiter("&") => try!(writer.write_str("&")),
372 SplitType::Delimiter("'") => try!(writer.write_str("'")),
373 SplitType::Delimiter("\"") => try!(writer.write_str(""")),
374 SplitType::Delimiter(..) => unreachable!(),
375 }
376 }
377 Ok(())
378 }
379
380 fn format_element<'d, W: ?Sized>(&self,
381 element: dom::Element<'d>,
382 todo: &mut Vec<Content<'d>>,
383 mapping: &mut PrefixMapping<'d>,
384 writer: &mut W)
385 -> io::Result<()>
386 where W: Write
387 {
388 let attrs = element.attributes();
389
390 mapping.populate_scope(&element, &attrs);
391
392 try!(writer.write_str("<"));
393 try!(self.format_qname(element.name(), mapping, element.preferred_prefix(), false, writer));
394
395 for attr in &attrs {
396 try!(writer.write_str(" "));
397 try!(self.format_qname(attr.name(), mapping, attr.preferred_prefix(), true, writer));
398 try!(write!(writer, "="));
399 try!(write!(writer, "{}", self.quote_char()));
400 try!(self.format_attribute_value(attr.value(), writer));
401 try!(write!(writer, "{}", self.quote_char()));
402 }
403
404 if let Some(ns_uri) = mapping.default_namespace_uri_in_current_scope() {
405 try!(writer.write_str(" xmlns='"));
406 try!(writer.write_str(ns_uri));
407 try!(writer.write_str("'"));
408 }
409
410 for &(ref prefix, ref ns_uri) in mapping.prefixes_in_current_scope() {
411 try!(writer.write_str(" xmlns:"));
412 try!(writer.write_str(prefix));
413 try!(write!(writer, "='{}'", ns_uri));
414 }
415
416 let mut children = element.children();
417 if children.is_empty() {
418 try!(writer.write_str("/>"));
419 mapping.pop_scope();
420 Ok(())
421 } else {
422 try!(writer.write_str(">"));
423
424 todo.push(ElementEnd(element));
425 children.reverse();
426 let x = children.into_iter().map(|c| match c {
427 ChildOfElement::Element(element) => Element(element),
428 ChildOfElement::Text(t) => Text(t),
429 ChildOfElement::Comment(c) => Comment(c),
430 ChildOfElement::ProcessingInstruction(p) => ProcessingInstruction(p),
431 });
432 todo.extend(x);
433
434 Ok(())
435 }
436 }
437
438 fn format_element_end<'d, W: ?Sized>(&self,
439 element: dom::Element<'d>,
440 mapping: &mut PrefixMapping<'d>,
441 writer: &mut W)
442 -> io::Result<()>
443 where W: Write
444 {
445 try!(writer.write_str("</"));
446 try!(self.format_qname(element.name(), mapping, element.preferred_prefix(), false, writer));
447 writer.write_str(">")
448 }
449
450 fn format_text<W: ?Sized>(&self, text: dom::Text, writer: &mut W) -> io::Result<()>
451 where W: Write
452 {
453 for item in text.text().split_keeping_delimiter(|c| c == '<' || c == '>' || c == '&') {
454 match item {
455 SplitType::Match(t) => try!(writer.write_str(t)),
456 SplitType::Delimiter("<") => try!(writer.write_str("<")),
457 SplitType::Delimiter(">") => try!(writer.write_str(">")),
458 SplitType::Delimiter("&") => try!(writer.write_str("&")),
459 SplitType::Delimiter(..) => unreachable!(),
460 }
461 }
462 Ok(())
463 }
464
465 fn format_comment<W: ?Sized>(&self, comment: dom::Comment, writer: &mut W) -> io::Result<()>
466 where W: Write
467 {
468 write!(writer, "<!--{}-->", comment.text())
469 }
470
471 fn format_processing_instruction<W: ?Sized>(&self, pi: dom::ProcessingInstruction, writer: &mut W)
472 -> io::Result<()>
473 where W: Write
474 {
475 match pi.value() {
476 None => write!(writer, "<?{}?>", pi.target()),
477 Some(v) => write!(writer, "<?{} {}?>", pi.target(), v),
478 }
479 }
480
481 fn format_one<'d, W: ?Sized>(&self,
482 content: Content<'d>,
483 todo: &mut Vec<Content<'d>>,
484 mapping: &mut PrefixMapping<'d>,
485 writer: &mut W)
486 -> io::Result<()>
487 where W: Write
488 {
489 match content {
490 Element(e) => {
491 mapping.push_scope();
492 self.format_element(e, todo, mapping, writer)
493 },
494 ElementEnd(e) => {
495 let r = self.format_element_end(e, mapping, writer);
496 mapping.pop_scope();
497 r
498 },
499 Text(t) => self.format_text(t, writer),
500 Comment(c) => self.format_comment(c, writer),
501 ProcessingInstruction(p) => self.format_processing_instruction(p, writer),
502 }
503 }
504
505 fn format_body<W: ?Sized>(&self, element: dom::Element, writer: &mut W) -> io::Result<()>
506 where W: Write
507 {
508 let mut todo = vec![Element(element)];
509 let mut mapping = PrefixMapping::new();
510
511 while ! todo.is_empty() {
512 try!(self.format_one(todo.pop().unwrap(), &mut todo, &mut mapping, writer));
513 }
514
515 Ok(())
516 }
517
518 fn format_declaration<'d, W: ?Sized>(&self, writer: &mut W) -> io::Result<()>
519 where W: Write
520 {
521 try!(write!(writer, "<?xml version={}1.0{}", self.quote_char(), self.quote_char()));
522
523 if self.write_encoding {
524 try!(write!(writer, " encoding={}UTF-8{}", self.quote_char(), self.quote_char()));
525 }
526
527 try!(write!(writer, "?>"));
528
529 Ok(())
530 }
531
532 pub fn format_document<'d, W: ?Sized>(&self, doc: &'d dom::Document<'d>, writer: &mut W) -> io::Result<()>
534 where W: Write
535 {
536 try!(self.format_declaration(writer));
537
538 for child in doc.root().children().into_iter() {
539 try!(match child {
540 ChildOfRoot::Element(e) => self.format_body(e, writer),
541 ChildOfRoot::Comment(c) => self.format_comment(c, writer),
542 ChildOfRoot::ProcessingInstruction(p) => self.format_processing_instruction(p, writer),
543 })
544 }
545
546 Ok(())
547 }
548}
549
550pub fn format_document<'d, W: ?Sized>(doc: &'d dom::Document<'d>, writer: &mut W) -> io::Result<()>
552 where W: Write
553{
554 Writer::default().format_document(doc, writer)
555}
556
557#[cfg(test)]
558mod test {
559 use super::super::Package;
560 use super::super::dom;
561 use super::Writer;
562
563 fn format_xml<'d>(doc: &'d dom::Document<'d>) -> String {
564 format_xml_writer(Writer::default(), doc)
565 }
566
567 fn format_xml_writer<'d>(writer: Writer, doc: &'d dom::Document) -> String {
568 let mut w = Vec::new();
569 writer.format_document(doc, &mut w).expect("Not formatted");
570 String::from_utf8(w).expect("Not a string")
571 }
572
573 #[test]
574 fn top_element() {
575 let p = Package::new();
576 let d = p.as_document();
577 let e = d.create_element("hello");
578 d.root().append_child(e);
579
580 let xml = format_xml(&d);
581 assert_eq!(xml, "<?xml version='1.0'?><hello/>");
582 }
583
584 #[test]
585 fn element_with_namespace() {
586 let p = Package::new();
587 let d = p.as_document();
588 let e = d.create_element(("namespace", "local-part"));
589 d.root().append_child(e);
590
591 let xml = format_xml(&d);
592 assert_eq!(xml, "<?xml version='1.0'?><autons0:local-part xmlns:autons0='namespace'/>");
593 }
594
595 #[test]
596 fn element_with_default_namespace() {
597 let p = Package::new();
598 let d = p.as_document();
599 let e = d.create_element(("namespace", "local-part"));
600 e.set_default_namespace_uri(Some("namespace"));
601 d.root().append_child(e);
602
603 let xml = format_xml(&d);
604 assert_eq!(xml, "<?xml version='1.0'?><local-part xmlns='namespace'/>");
605 }
606
607 #[test]
608 fn element_with_preferred_namespace_prefix() {
609 let p = Package::new();
610 let d = p.as_document();
611 let e = d.create_element(("namespace", "local-part"));
612 e.set_preferred_prefix(Some("prefix"));
613 d.root().append_child(e);
614
615 let xml = format_xml(&d);
616 assert_eq!(xml, "<?xml version='1.0'?><prefix:local-part xmlns:prefix='namespace'/>");
617 }
618
619 #[test]
620 fn element_with_attributes() {
621 let p = Package::new();
622 let d = p.as_document();
623 let e = d.create_element("hello");
624 e.set_attribute_value("a", "b");
625 d.root().append_child(e);
626
627 let xml = format_xml(&d);
628 assert_eq!(xml, "<?xml version='1.0'?><hello a='b'/>");
629 }
630
631 #[test]
632 fn element_with_attributes_double_quotes() {
633 let p = Package::new();
634 let d = p.as_document();
635 let e = d.create_element("hello");
636 e.set_attribute_value("a", "b");
637 d.root().append_child(e);
638
639 let xml = format_xml_writer(Writer::new().set_single_quotes(false), &d);
640 assert_eq!(xml, r#"<?xml version="1.0"?><hello a="b"/>"#);
641 }
642
643
644 #[test]
645 fn attribute_with_namespace() {
646 let p = Package::new();
647 let d = p.as_document();
648 let e = d.create_element("hello");
649 e.set_attribute_value(("namespace", "a"), "b");
650 d.root().append_child(e);
651
652 let xml = format_xml(&d);
653 assert_eq!(xml, "<?xml version='1.0'?><hello autons0:a='b' xmlns:autons0='namespace'/>");
654 }
655
656 #[test]
657 fn attribute_with_preferred_namespace_prefix() {
658 let p = Package::new();
659 let d = p.as_document();
660 let e = d.create_element("hello");
661 let a = e.set_attribute_value(("namespace", "a"), "b");
662 a.set_preferred_prefix(Some("p"));
663 d.root().append_child(e);
664
665 let xml = format_xml(&d);
666 assert_eq!(xml, "<?xml version='1.0'?><hello p:a='b' xmlns:p='namespace'/>");
667 }
668
669 #[test]
670 fn attribute_with_default_namespace_prefix() {
671 let p = Package::new();
672 let d = p.as_document();
673 let e = d.create_element(("namespace", "hello"));
674 e.set_preferred_prefix(Some("p"));
675 e.set_default_namespace_uri(Some("namespace"));
676 e.set_attribute_value(("namespace", "a"), "b");
677 d.root().append_child(e);
678
679 let xml = format_xml(&d);
680 assert_eq!(xml, "<?xml version='1.0'?><hello p:a='b' xmlns='namespace' xmlns:p='namespace'/>");
681 }
682
683 #[test]
684 fn attributes_with_conflicting_preferred_namespace_prefixes() {
685 let p = Package::new();
686 let d = p.as_document();
687 let e = d.create_element("hello");
688
689 let a = e.set_attribute_value(("namespace1", "a1"), "b1");
690 a.set_preferred_prefix(Some("p"));
691
692 let a = e.set_attribute_value(("namespace2", "a2"), "b2");
693 a.set_preferred_prefix(Some("p"));
694
695 d.root().append_child(e);
696
697 let xml = format_xml(&d);
698 assert_eq!(xml, "<?xml version='1.0'?><hello p:a1='b1' autons0:a2='b2' xmlns:p='namespace1' xmlns:autons0='namespace2'/>");
699 }
700
701 #[test]
702 fn attributes_with_different_preferred_namespace_prefixes_for_same_namespace() {
703 let p = Package::new();
704 let d = p.as_document();
705 let e = d.create_element("hello");
706
707 let a = e.set_attribute_value(("namespace", "a1"), "b1");
708 a.set_preferred_prefix(Some("p1"));
709
710 let a = e.set_attribute_value(("namespace", "a2"), "b2");
711 a.set_preferred_prefix(Some("p2"));
712
713 d.root().append_child(e);
714
715 let xml = format_xml(&d);
716 assert_eq!(xml, "<?xml version='1.0'?><hello p1:a1='b1' p2:a2='b2' xmlns:p1='namespace' xmlns:p2='namespace'/>");
717 }
718
719 #[test]
720 fn attribute_values_with_less_than_greater_than_ampersand_apostrophe_or_quote_are_escaped() {
721 let p = Package::new();
722 let d = p.as_document();
723 let e = d.create_element("hello");
724 e.set_attribute_value("name", r#"'1 < 2' & "4 > 3""#);
725 d.root().append_child(e);
726
727 let xml = format_xml(&d);
728 assert_eq!(xml, "<?xml version='1.0'?><hello name=''1 < 2' & "4 > 3"'/>");
729 }
730
731 #[test]
732 fn nested_element() {
733 let p = Package::new();
734 let d = p.as_document();
735 let hello = d.create_element("hello");
736 let world = d.create_element("world");
737 hello.append_child(world);
738 d.root().append_child(hello);
739
740 let xml = format_xml(&d);
741 assert_eq!(xml, "<?xml version='1.0'?><hello><world/></hello>");
742 }
743
744 #[test]
745 fn nested_element_with_namespaces() {
746 let p = Package::new();
747 let d = p.as_document();
748 let hello = d.create_element(("outer", "hello"));
749 let world = d.create_element(("inner", "world"));
750 hello.append_child(world);
751 d.root().append_child(hello);
752
753 let xml = format_xml(&d);
754 assert_eq!(xml, "<?xml version='1.0'?><autons0:hello xmlns:autons0='outer'><autons1:world xmlns:autons1='inner'/></autons0:hello>");
755 }
756
757 #[test]
758 fn nested_empty_element_with_namespaces() {
759 let p = Package::new();
760 let d = p.as_document();
761
762 let hello = d.create_element(("outer", "hello"));
763 hello.set_default_namespace_uri(Some("outer"));
764 hello.set_preferred_prefix(Some("o"));
765
766 let world = d.create_element("world");
767 world.set_default_namespace_uri(Some("inner"));
768
769 let empty = d.create_element("empty");
770 world.append_child(empty);
771 hello.append_child(world);
772 d.root().append_child(hello);
773
774 let xml = format_xml(&d);
775 assert_eq!(xml, "<?xml version='1.0'?><hello xmlns='outer' xmlns:o='outer'><world xmlns='inner'><empty/></world></hello>");
776 }
777
778 #[test]
779 fn nested_element_with_namespaces_with_reused_namespaces() {
780 let p = Package::new();
781 let d = p.as_document();
782 let hello = d.create_element(("ns", "hello"));
783 let world = d.create_element(("ns", "world"));
784 hello.append_child(world);
785 d.root().append_child(hello);
786
787 let xml = format_xml(&d);
788 assert_eq!(xml, "<?xml version='1.0'?><autons0:hello xmlns:autons0='ns'><autons0:world/></autons0:hello>");
789 }
790
791 #[test]
792 fn nested_element_with_with_conflicting_preferred_namespace_prefixes() {
793 let p = Package::new();
794 let d = p.as_document();
795 let hello = d.create_element(("outer", "hello"));
796 let world = d.create_element(("inner", "world"));
797 hello.set_preferred_prefix(Some("p"));
798 world.set_preferred_prefix(Some("p"));
799 hello.append_child(world);
800 d.root().append_child(hello);
801
802 let xml = format_xml(&d);
803 assert_eq!(xml, "<?xml version='1.0'?><p:hello xmlns:p='outer'><p:world xmlns:p='inner'/></p:hello>");
804 }
805
806 #[test]
807 fn nested_text() {
808 let p = Package::new();
809 let d = p.as_document();
810 let hello = d.create_element("hello");
811 let text = d.create_text("A fine day to you!");
812 hello.append_child(text);
813 d.root().append_child(hello);
814
815 let xml = format_xml(&d);
816 assert_eq!(xml, "<?xml version='1.0'?><hello>A fine day to you!</hello>");
817 }
818
819 #[test]
820 fn text_escapes_less_than_greater_than_and_ampersand() {
821 let p = Package::new();
822 let d = p.as_document();
823 let hello = d.create_element("escaped");
824 let text = d.create_text("1 < 3 & 4 > 2");
825 hello.append_child(text);
826 d.root().append_child(hello);
827
828 let xml = format_xml(&d);
829 assert_eq!(xml, "<?xml version='1.0'?><escaped>1 < 3 & 4 > 2</escaped>");
830 }
831
832 #[test]
833 fn nested_comment() {
834 let p = Package::new();
835 let d = p.as_document();
836 let hello = d.create_element("hello");
837 let comment = d.create_comment(" Fill this in ");
838 hello.append_child(comment);
839 d.root().append_child(hello);
840
841 let xml = format_xml(&d);
842 assert_eq!(xml, "<?xml version='1.0'?><hello><!-- Fill this in --></hello>");
843 }
844
845 #[test]
846 fn nested_processing_instruction_without_value() {
847 let p = Package::new();
848 let d = p.as_document();
849 let hello = d.create_element("hello");
850 let pi = d.create_processing_instruction("display", None);
851 hello.append_child(pi);
852 d.root().append_child(hello);
853
854 let xml = format_xml(&d);
855 assert_eq!(xml, "<?xml version='1.0'?><hello><?display?></hello>");
856 }
857
858 #[test]
859 fn nested_processing_instruction_with_value() {
860 let p = Package::new();
861 let d = p.as_document();
862 let hello = d.create_element("hello");
863 let pi = d.create_processing_instruction("display", Some("screen"));
864 hello.append_child(pi);
865 d.root().append_child(hello);
866
867 let xml = format_xml(&d);
868 assert_eq!(xml, "<?xml version='1.0'?><hello><?display screen?></hello>");
869 }
870
871 #[test]
872 fn top_level_comment() {
873 let p = Package::new();
874 let d = p.as_document();
875 let comment = d.create_comment(" Fill this in ");
876 d.root().append_child(comment);
877
878 let xml = format_xml(&d);
879 assert_eq!(xml, "<?xml version='1.0'?><!-- Fill this in -->");
880 }
881
882 #[test]
883 fn top_level_processing_instruction() {
884 let p = Package::new();
885 let d = p.as_document();
886 let pi = d.create_processing_instruction("display", None);
887 d.root().append_child(pi);
888
889 let xml = format_xml(&d);
890 assert_eq!(xml, "<?xml version='1.0'?><?display?>");
891 }
892
893 #[test]
894 fn declaration_with_encoding() {
895 let p = Package::new();
896 let d = p.as_document();
897 let e = d.create_element("hello");
898 d.root().append_child(e);
899
900 let xml = format_xml_writer(Writer::new().set_write_encoding(true), &d);
901 assert_eq!(xml, "<?xml version='1.0' encoding='UTF-8'?><hello/>");
902 }
903
904 #[test]
905 fn declaration_with_encoding_and_double_quotes() {
906 let p = Package::new();
907 let d = p.as_document();
908 let e = d.create_element("hello");
909 d.root().append_child(e);
910
911 let xml = format_xml_writer(Writer::new()
912 .set_write_encoding(true)
913 .set_single_quotes(false), &d);
914 assert_eq!(xml, r#"<?xml version="1.0" encoding="UTF-8"?><hello/>"#);
915 }
916}