FEATURE: Add xml namespace support.

This commit is contained in:
Jeremy Wall 2018-12-12 20:26:19 -06:00
parent 3d017a76da
commit 0a09f26aad
2 changed files with 56 additions and 25 deletions

View File

@ -1,26 +1,30 @@
let make_element = macro(name, attrs, children) => {
name = name,
attrs = attrs,
children = children,
};
let doc = { let doc = {
root = make_element( root = {
"top", ns = {
{id = "foo"}, prefix = "myns",
[ uri = "http://example.com",
make_element( },
"child1", name = "top",
{ attr1 = "value1", attr2 = "value2"}, attrs = {id = "foo"},
[ children = [
"inner text content", {
make_element( ns = "http://example.org/",
"grandchild", name = "child1",
{}, attrs = { attr1 = "value1", attr2 = "value2"},
[{ children = [
text = "Another text node", "inner text node",
}]), {
])]), name = "myns:grandchild",
children = [
{
text = "Another text node",
},
],
},
],
},
],
},
}; };
out xml doc; out xml doc;

View File

@ -77,13 +77,33 @@ impl XmlConverter {
let mut attrs: Option<&Vec<(PositionedItem<String>, Rc<Val>)>> = None; let mut attrs: Option<&Vec<(PositionedItem<String>, Rc<Val>)>> = None;
let mut children: Option<&Vec<Rc<Val>>> = None; let mut children: Option<&Vec<Rc<Val>>> = None;
let mut text: Option<&str> = None; let mut text: Option<&str> = None;
let mut ns: Option<(&str, &str)> = None;
for (ref field, ref val) in fs.iter() { for (ref field, ref val) in fs.iter() {
if field.val == "name" { if field.val == "name" {
name = Some(Self::get_str_val(val.as_ref())?); name = Some(Self::get_str_val(val.as_ref())?);
} }
//if field.val == "namespace" { if field.val == "ns" {
// namespace = Some(Self::get_str_val(val.as_ref())?); if let Val::Tuple(ref fs) = val.as_ref() {
//} let mut prefix = "";
let mut uri = "";
for (ref name, ref val) in fs.iter() {
if val.is_empty() {
continue;
}
if name.val == "uri" {
uri = Self::get_str_val(val.as_ref())?;
}
if name.val == "prefix" {
prefix = Self::get_str_val(val.as_ref())?;
}
}
if uri != "" && prefix != "" {
ns = Some((prefix, uri));
}
} else if let Val::Str(ref s) = val.as_ref() {
ns = Some(("", s));
}
}
if field.val == "attrs" { if field.val == "attrs" {
// This should be a tuple. // This should be a tuple.
if !val.is_empty() { if !val.is_empty() {
@ -119,6 +139,13 @@ impl XmlConverter {
start = start.attr(name.val.as_ref(), Self::get_str_val(val.as_ref())?); start = start.attr(name.val.as_ref(), Self::get_str_val(val.as_ref())?);
} }
} }
if let Some((prefix, uri)) = ns {
if prefix == "" {
start = start.default_ns(uri);
} else {
start = start.ns(prefix, uri);
}
}
w.write(start)?; w.write(start)?;
if children.is_some() { if children.is_some() {
for child in children.unwrap().iter() { for child in children.unwrap().iter() {