From 6f0e88b25beab91b921090d1bbd4879105b1140b Mon Sep 17 00:00:00 2001 From: Eijebong Date: Mon, 24 Apr 2017 16:56:29 +0200 Subject: [PATCH] Correctly add namespaced attributes to elements Instead of adding the local_name of an attribute, if a prefix exists, add prefix:local_name to allow users to retrieve it via the namespaced key name. For example, with this XML: ``` ``` `root.attr("xml:lang").unwrap()` will now correctly return "en". `root.attr("lang")` will not retrieve "xml:lang" value anymore. This is a breaking change. Fixes #2 --- src/element.rs | 21 +++++++++++++++++++-- src/tests.rs | 12 +++++++++++- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/element.rs b/src/element.rs index 13c8baf1..0db7ba81 100644 --- a/src/element.rs +++ b/src/element.rs @@ -197,7 +197,15 @@ impl Element { match e { ReaderEvent::StartElement { name, attributes, namespace } => { let attributes = attributes.into_iter() - .map(|o| Attribute::new(o.name.local_name, o.value)) + .map(|o| { + Attribute::new( + match o.name.prefix { + Some(prefix) => format!("{}:{}", prefix, o.name.local_name), + None => o.name.local_name + }, + o.value + ) + }) .collect(); let ns = if let Some(ref prefix) = name.prefix { namespace.get(prefix) @@ -205,6 +213,7 @@ impl Element { else { namespace.get(NS_NO_PREFIX) }.map(|s| s.to_owned()); + let mut root = Element::new(name.local_name, ns, attributes, Vec::new()); root.from_reader_inner(reader)?; return Ok(root); @@ -223,7 +232,15 @@ impl Element { match e { ReaderEvent::StartElement { name, attributes, namespace } => { let attributes = attributes.into_iter() - .map(|o| Attribute::new(o.name.local_name, o.value)) + .map(|o| { + Attribute::new( + match o.name.prefix { + Some(prefix) => format!("{}:{}", prefix, o.name.local_name), + None => o.name.local_name + }, + o.value + ) + }) .collect(); let ns = if let Some(ref prefix) = name.prefix { namespace.get(prefix) diff --git a/src/tests.rs b/src/tests.rs index b9263446..03d3ab9a 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -7,11 +7,12 @@ use xml::writer::EventWriter; use element::Element; -const TEST_STRING: &'static str = r#"meownya"#; +const TEST_STRING: &'static str = r#"meownya"#; fn build_test_tree() -> Element { let mut root = Element::builder("root") .ns("root_ns") + .attr("xml:lang", "en") .attr("a", "b") .build(); root.append_text_node("meow"); @@ -22,6 +23,7 @@ fn build_test_tree() -> Element { let other_child = Element::builder("child") .ns("child_ns") .attr("d", "e") + .attr("xml:lang", "fr") .build(); root.append_child(other_child); root.append_text_node("nya"); @@ -94,3 +96,11 @@ fn namespace_propagation_works() { .get_child("grandchild", "root_ns").unwrap() .ns(), root.ns()); } + +#[test] +fn namespace_attributes_works() { + let mut reader = EventReader::new(Cursor::new(TEST_STRING)); + let root = Element::from_reader(&mut reader).unwrap(); + assert_eq!("en", root.attr("xml:lang").unwrap()); + assert_eq!("fr", root.get_child("child", "child_ns").unwrap().attr("xml:lang").unwrap()); +}