pub trait EntityResolver {
type Error: Error;
// Required methods
fn capture(&mut self, doctype: BytesText<'_>) -> Result<(), Self::Error>;
fn resolve(&self, entity: &str) -> Option<&str>;
}
Available on crate feature
serialize
only.Expand description
Used to resolve unknown entities while parsing
§Example
use regex::bytes::Regex;
use std::collections::BTreeMap;
use std::string::FromUtf8Error;
use quick_xml::de::{Deserializer, EntityResolver};
use quick_xml::events::BytesText;
struct DocTypeEntityResolver {
re: Regex,
map: BTreeMap<String, String>,
}
impl Default for DocTypeEntityResolver {
fn default() -> Self {
Self {
// We do not focus on true parsing in this example
// You should use special libraries to parse DTD
re: Regex::new(r#"<!ENTITY\s+([^ \t\r\n]+)\s+"([^"]*)"\s*>"#).unwrap(),
map: BTreeMap::new(),
}
}
}
impl EntityResolver for DocTypeEntityResolver {
type Error = FromUtf8Error;
fn capture(&mut self, doctype: BytesText) -> Result<(), Self::Error> {
for cap in self.re.captures_iter(&doctype) {
self.map.insert(
String::from_utf8(cap[1].to_vec())?,
String::from_utf8(cap[2].to_vec())?,
);
}
Ok(())
}
fn resolve(&self, entity: &str) -> Option<&str> {
self.map.get(entity).map(|s| s.as_str())
}
}
let xml_reader = br#"
<!DOCTYPE dict[ <!ENTITY e1 "entity 1"> ]>
<root>
<entity_one>&e1;</entity_one>
</root>
"#.as_ref();
let mut de = Deserializer::with_resolver(
xml_reader,
DocTypeEntityResolver::default(),
);
let data: BTreeMap<String, String> = BTreeMap::deserialize(&mut de).unwrap();
assert_eq!(data.get("entity_one"), Some(&"entity 1".to_string()));