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:
```
<?xml version="1.0" encoding="utf-8"?>
<root xml:lang="en" >
</root>
```

`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
This commit is contained in:
Eijebong 2017-04-24 16:56:29 +02:00
parent 8f027cfee2
commit 6f0e88b25b
2 changed files with 30 additions and 3 deletions

View file

@ -197,7 +197,15 @@ impl Element {
match e { match e {
ReaderEvent::StartElement { name, attributes, namespace } => { ReaderEvent::StartElement { name, attributes, namespace } => {
let attributes = attributes.into_iter() 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(); .collect();
let ns = if let Some(ref prefix) = name.prefix { let ns = if let Some(ref prefix) = name.prefix {
namespace.get(prefix) namespace.get(prefix)
@ -205,6 +213,7 @@ impl Element {
else { else {
namespace.get(NS_NO_PREFIX) namespace.get(NS_NO_PREFIX)
}.map(|s| s.to_owned()); }.map(|s| s.to_owned());
let mut root = Element::new(name.local_name, ns, attributes, Vec::new()); let mut root = Element::new(name.local_name, ns, attributes, Vec::new());
root.from_reader_inner(reader)?; root.from_reader_inner(reader)?;
return Ok(root); return Ok(root);
@ -223,7 +232,15 @@ impl Element {
match e { match e {
ReaderEvent::StartElement { name, attributes, namespace } => { ReaderEvent::StartElement { name, attributes, namespace } => {
let attributes = attributes.into_iter() 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(); .collect();
let ns = if let Some(ref prefix) = name.prefix { let ns = if let Some(ref prefix) = name.prefix {
namespace.get(prefix) namespace.get(prefix)

View file

@ -7,11 +7,12 @@ use xml::writer::EventWriter;
use element::Element; use element::Element;
const TEST_STRING: &'static str = r#"<?xml version="1.0" encoding="utf-8"?><root xmlns="root_ns" a="b">meow<child c="d" /><child xmlns="child_ns" d="e" />nya</root>"#; const TEST_STRING: &'static str = r#"<?xml version="1.0" encoding="utf-8"?><root xmlns="root_ns" xml:lang="en" a="b">meow<child c="d" /><child xmlns="child_ns" d="e" xml:lang="fr" />nya</root>"#;
fn build_test_tree() -> Element { fn build_test_tree() -> Element {
let mut root = Element::builder("root") let mut root = Element::builder("root")
.ns("root_ns") .ns("root_ns")
.attr("xml:lang", "en")
.attr("a", "b") .attr("a", "b")
.build(); .build();
root.append_text_node("meow"); root.append_text_node("meow");
@ -22,6 +23,7 @@ fn build_test_tree() -> Element {
let other_child = Element::builder("child") let other_child = Element::builder("child")
.ns("child_ns") .ns("child_ns")
.attr("d", "e") .attr("d", "e")
.attr("xml:lang", "fr")
.build(); .build();
root.append_child(other_child); root.append_child(other_child);
root.append_text_node("nya"); root.append_text_node("nya");
@ -94,3 +96,11 @@ fn namespace_propagation_works() {
.get_child("grandchild", "root_ns").unwrap() .get_child("grandchild", "root_ns").unwrap()
.ns(), root.ns()); .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());
}