escape text and attribute values
This commit is contained in:
parent
8b50dadb92
commit
052c46635a
2 changed files with 51 additions and 3 deletions
|
@ -18,6 +18,22 @@ use std::slice;
|
|||
|
||||
use convert::{IntoElements, IntoAttributeValue, ElementEmitter};
|
||||
|
||||
/// Escape XML text
|
||||
pub fn write_escaped<W: Write>(writer: &mut W, input: &str) -> Result<()> {
|
||||
for c in input.chars() {
|
||||
match c {
|
||||
'&' => write!(writer, "&")?,
|
||||
'<' => write!(writer, "<")?,
|
||||
'>' => write!(writer, ">")?,
|
||||
'\'' => write!(writer, "'")?,
|
||||
'"' => write!(writer, """)?,
|
||||
_ => write!(writer, "{}", c)?,
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// A node in an element tree.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum Node {
|
||||
|
@ -71,7 +87,7 @@ impl Node {
|
|||
fn write_to_inner<W: Write>(&self, writer: &mut W, last_namespace: &mut Option<String>) -> Result<()>{
|
||||
match *self {
|
||||
Node::Element(ref elmt) => elmt.write_to_inner(writer, last_namespace)?,
|
||||
Node::Text(ref s) => write!(writer, "{}", s)?,
|
||||
Node::Text(ref s) => write_escaped(writer, s)?,
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -323,13 +339,17 @@ impl Element {
|
|||
|
||||
if let Some(ref ns) = self.namespace {
|
||||
if *last_namespace != self.namespace {
|
||||
write!(writer, " xmlns=\"{}\"", ns)?;
|
||||
write!(writer, " xmlns=\"")?;
|
||||
write_escaped(writer, ns)?;
|
||||
write!(writer, "\"")?;
|
||||
*last_namespace = Some(ns.clone());
|
||||
}
|
||||
}
|
||||
|
||||
for (key, value) in &self.attributes {
|
||||
write!(writer, " {}=\"{}\"", key, value)?;
|
||||
write!(writer, " {}=\"", key)?;
|
||||
write_escaped(writer, value)?;
|
||||
write!(writer, "\"")?;
|
||||
}
|
||||
|
||||
if self.children.is_empty() {
|
||||
|
|
28
src/tests.rs
28
src/tests.rs
|
@ -43,6 +43,34 @@ fn writer_works() {
|
|||
assert_eq!(String::from_utf8(writer).unwrap(), TEST_STRING);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn writer_escapes_attributes() {
|
||||
let root = Element::builder("root")
|
||||
.attr("a", "\"Air\" quotes")
|
||||
.build();
|
||||
let mut writer = Vec::new();
|
||||
{
|
||||
root.write_to(&mut writer).unwrap();
|
||||
}
|
||||
assert_eq!(String::from_utf8(writer).unwrap(),
|
||||
r#"<?xml version="1.0" encoding="utf-8"?><root a=""Air" quotes" />"#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn writer_escapes_text() {
|
||||
let root = Element::builder("root")
|
||||
.append("<3")
|
||||
.build();
|
||||
let mut writer = Vec::new();
|
||||
{
|
||||
root.write_to(&mut writer).unwrap();
|
||||
}
|
||||
assert_eq!(String::from_utf8(writer).unwrap(),
|
||||
r#"<?xml version="1.0" encoding="utf-8"?><root><3</root>"#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn builder_works() {
|
||||
let elem = Element::builder("a")
|
||||
|
|
Loading…
Reference in a new issue