Skip to main content

EntityResolver

Trait EntityResolver 

Source
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 std::collections::BTreeMap;
use std::string::FromUtf8Error;
use oxixml_xml::de::{Deserializer, EntityResolver};
use oxixml_xml::events::BytesText;

#[derive(Default)]
struct DocTypeEntityResolver {
    map: BTreeMap<String, String>,
}

impl EntityResolver for DocTypeEntityResolver {
    type Error = FromUtf8Error;

    fn capture(&mut self, doctype: BytesText) -> Result<(), Self::Error> {
        // We do not focus on true parsing in this example: this only handles
        // `<!ENTITY name "value">` declarations. You should use a dedicated
        // DTD parser in real code.
        let text = String::from_utf8(doctype.to_vec())?;
        let mut rest = text.as_str();
        while let Some(start) = rest.find("<!ENTITY") {
            rest = rest[start + "<!ENTITY".len()..].trim_start();
            let name_len = rest.find(char::is_whitespace).unwrap_or(rest.len());
            let name = rest[..name_len].to_string();
            rest = &rest[name_len..];

            let Some(open) = rest.find('"') else { break };
            rest = &rest[open + 1..];
            let Some(close) = rest.find('"') else { break };
            self.map.insert(name, rest[..close].to_string());
            rest = &rest[close + 1..];
        }
        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).expect("should be Ok");

assert_eq!(data.get("entity_one"), Some(&"entity 1".to_string()));

Required Associated Types§

Source

type Error: Error

The error type that represents DTD parse error

Required Methods§

Source

fn capture(&mut self, doctype: BytesText<'_>) -> Result<(), Self::Error>

Called on contents of Event::DocType to capture declared entities. Can be called multiple times, for each parsed <!DOCTYPE > declaration.

Source

fn resolve(&self, entity: &str) -> Option<&str>

Called when an entity needs to be resolved.

None is returned if a suitable value can not be found. In that case an EscapeError::UnrecognizedEntity will be returned by a deserializer.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§