From 88bed66f63b46d2063ba8f30d75973730d6d1552 Mon Sep 17 00:00:00 2001 From: Jake Goulding Date: Sat, 1 Jul 2017 17:12:14 -0700 Subject: [PATCH] Understand the "xml" namespace prefix when parsing into the DOM This does not yet *do* anything with the attributes; it only stops them from preventing a successful parse. Related to #46 --- src/lib.rs | 3 +++ src/parser.rs | 22 ++++++++++++++++++++++ src/raw.rs | 5 +---- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ee1217d..51c956a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -72,6 +72,9 @@ pub mod writer; pub use str::XmlChar; +static XML_NS_PREFIX: &'static str = "xml"; +static XML_NS_URI: &'static str = "http://www.w3.org/XML/1998/namespace"; + /// A prefixed name. This represents what is found in the string form /// of an XML document, and does not apply any namespace mapping. #[derive(Debug,Copy,Clone,PartialEq,Eq,PartialOrd,Ord)] diff --git a/src/parser.rs b/src/parser.rs index 9907d9d..369798a 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -798,6 +798,7 @@ struct DomBuilder<'d> { elements: Vec>, element_names: Vec>>, attributes: Vec>, + seen_top_element: bool, } impl<'d> DomBuilder<'d> { @@ -807,6 +808,7 @@ impl<'d> DomBuilder<'d> { elements: vec![], element_names: Vec::new(), attributes: Vec::new(), + seen_top_element: false, } } @@ -879,6 +881,11 @@ impl<'d> DomBuilder<'d> { element.register_prefix(*prefix, ns_uri); } + if !self.seen_top_element { + self.seen_top_element = true; + element.register_prefix(::XML_NS_PREFIX, ::XML_NS_URI); + } + self.append_to_either(element); self.elements.push(element); @@ -1326,6 +1333,21 @@ mod test { assert_eq!(attr.value(), "b"); } + #[test] + fn an_attribute_with_xml_space_preserve() { + let package = quick_parse(" "); + let doc = package.as_document(); + let top = top(&doc); + + assert_eq!(top.attribute((::XML_NS_URI, "space")).unwrap().value(), "preserve"); + + let children = top.children(); + assert_eq!(children.len(), 3); + assert_eq!(children[0].text().unwrap().text(), " "); + assert_qname_eq!(children[1].element().unwrap().name(), "a"); + assert_eq!(children[2].text().unwrap().text(), " "); + } + #[test] fn an_attribute_with_references() { let package = quick_parse(""); diff --git a/src/raw.rs b/src/raw.rs index 4517810..47717e2 100644 --- a/src/raw.rs +++ b/src/raw.rs @@ -6,9 +6,6 @@ use string_pool::{StringPool,InternedString}; use std::marker::PhantomData; use std::slice; -static XML_NS_PREFIX: &'static str = "xml"; -static XML_NS_URI: &'static str = "http://www.w3.org/XML/1998/namespace"; - struct InternedQName { namespace_uri: Option, local_part: InternedString, @@ -644,7 +641,7 @@ impl Connections { { let mut namespaces = Vec::new(); - namespaces.push((XML_NS_PREFIX, XML_NS_URI)); + namespaces.push((::XML_NS_PREFIX, ::XML_NS_URI)); let all_namespaces = self.element_parents(element)