# Crate xml_dom A Rust crate providing a reasonably faithful implementation of the W3C [Document Object Model Core, Level 2](https://www.w3.org/TR/DOM-Level-2-Core). ![MIT License](https://img.shields.io/badge/license-mit-118811.svg) ![Minimum Rust Version](https://img.shields.io/badge/Min%20Rust-1.40-green.svg) [![crates.io](https://img.shields.io/crates/v/xml_dom.svg)](https://crates.io/crates/xml_dom) [![docs.rs](https://docs.rs/xml_dom/badge.svg)](https://docs.rs/xml_dom) ![Build](https://github.com/johnstonskj/rust-xml_dom/workflows/Rust/badge.svg) ![Audit](https://github.com/johnstonskj/rust-xml_dom/workflows/Security%20audit/badge.svg) [![GitHub stars](https://img.shields.io/github/stars/johnstonskj/rust-xml_dom.svg)](https://github.com/johnstonskj/rust-xml_dom/stargazers) This crate provides a trait-based implementation of the DOM with minimal changes to the style and semantics defined in the Level 2 specification. The specific mapping from the IDL in the specification is described in the documentation, however from a purely style point of view the implementation has the following characteristics: 1. It maintains a reasonable separation between the node type traits and the tree implementation using opaque an `RefNode` reference type. 1. Where possible the names from IDL are used with minimal conversion. 1. All IDL attributes become trait functions (attribute "foo" becomes `foo()`, `set_foo()`, and `unset_foo()`). This leads to a replication of the typical DOM programmer experience where casting between the node traits is required. This is supported by the `xml_dom::convert` module. ## Example ```rust use xml_dom::level2::*; use xml_dom::level2::convert::*; // Bootstrap; get an instance of `DOMImplementation`. The mechanism for this is // intentionally undefined by the specification. let implementation = get_implementation(); // Create a `DocumentType` instance. let document_type = implementation .create_document_type( "html", Some("-//W3C//DTD XHTML 1.0 Transitional//EN"), Some("http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"), ) .unwrap(); // Create a new `Document` using the document type defined above. Note that this // also has the side-effect of creating the document's root element named "html". let mut document_node = implementation .create_document( Some("http://www.w3.org/1999/xhtml"), Some("html"), Some(document_type)) .unwrap(); // Cast the returned document `RefNode` into a `RefDocument` trait reference let document = as_document_mut(&mut document_node).unwrap(); // Fetch the document's root element as a node, then cast to `RefElement`. let mut root_node = document.document_element().unwrap(); let root = as_element_mut(&mut root_node).unwrap(); // Create an `Attribute` instance on the root element. root.set_attribute("lang", "en"); // Create two child `Element`s of "html". let _head = root.append_child(document.create_element("head").unwrap()); let _body = root.append_child(document.create_element("body").unwrap()); // Display as XML. let xml = document_node.to_string(); println!("document 2: {}", xml); ``` This should result in the following XML; note that formatting was added for this document, the provided implementation of `Display` for `RefNode` does not format the output. ```xml ``` ## Features Currently only one feature, `quick_parser`, is provided which provides a new module `parser` with the single public function. This feature is enabled by default. ``` rust pub fn read_xml(xml: AsRef) -> Result; ``` This will parse the document and return a new `RefNode` that corresponds to the `Document` trait. ## Changes ### Version 0.2.8 * Dependency management: * Updated `quick-xml` which had some breaking API changes. * Moved from `log` crate to `tracing`. * Removed `this_error` dependency. ### Version 0.2.7 * Updated to 2021 Edition of Rust * Updated [quick-xml](https://crates.io/crates/quick-xml) dependency. * Refactored `Error` type with [thiserror](https://crates.io/crates/thiserror) * Encapsulated errors from dependant libraries and removed manual `From` implementations. * Removed unused `Error` enum types. * Made several interfaces more generic with `AsRef` and `Into`. ### Version 0.2.6 * Updated [quick-xml](https://crates.io/crates/quick-xml) dependency. * Had to update the handling of errors from the underlying parser. * Had to handle the CData parser explicitly. ### Version 0.2.5 * Added `parser::from_reader` function alongside the existing `parser::from_str` to allow for streaming input of the underlying source. ### Version 0.2.4 * Updated [quick-xml](https://crates.io/crates/quick-xml) dependency. * Moved TODOs into [GitHub issues](https://github.com/johnstonskj/rust-xml_dom/issues). * Started migration to [GitHub actions](https://github.com/johnstonskj/rust-xml_dom/actions) for build. ### Version 0.2.3 * Mostly documentation updates/fixes. * Made namespace support respect `ProcessingOptions`. ### Version 0.2.2 * Mostly documentation updates/fixes. * Fixed a defect in handling of `xml:id`. ### Version 0.2.1 * Bug Fixes: * Fixed a publishing error in Travis * Separated `Attribute::owner_element` from `Node::parent_node`, they aren't the same. * Fixed handling of `owner_element` in `Attribute` tests * Fixed the implementation of `WrongDocument` error in `Node::insert_before` and used the same in `Element::set_attribute_node`. * Fixed escaping of values to happen on get not set. * Implemented _attribute value normalization_ and _end-of-line handling_ from the XML 1.1 spec. * Required added a dependency on [`regex`](https://crates.io/crates/regex) * Added `EntityResolver` trait for callback into DOM. * Expansion of `Entity` node children is not yet complete. * Code clean-up: * Added some macros in `trait_impls` for a number of common patterns. * Simplified some existing `match` expressions. ### Version 0.2.0 * Cleaned up documentation. * Stable release. ### Version 0.1.4 * **BREAKING** refactored to add a `level2` module, allowing other levels to be added at a later time. Also moved extensions into `level2::ext` module. * **BREAKING** renamed methods to conform with DOM names: * `Node::name` to `Node::node_name`; * `CharacterData::substring` to `CharacterData::substring_data`; * `CharacterData::append` to `CharacterData::append_data`; * `CharacterData::insert` to `CharacterData::insert_data`; * `CharacterData::delete` to `CharacterData::delete_data`; * `CharacterData::replace` to `CharacterData::replace_data`. * Implemented the following methods: * `Node::clone_node`; * `Node::normalize`; * `Namespaced::normalize_mappings`. * Added the following DOM methods: * `Attribute::owner_element`; * `Node::local_name`; * `Node::namespace_uri`; * `Node::prefix`. * CI builds now working with Travis, [rust-xml_dom](https://travis-ci.org/github/johnstonskj/rust-xml_dom). * Added `quick_xml` based text parser. * Make this the 0.2.0 candidate. ### Version 0.1.3 * More unit tests overall, especially for append/insert/replace child * Add support for xml declaration (`XmlDecl`, `XmlVersion`), not reusing processing instruction * Support the last Level 2 _extended interfaces_ (`Entity`, `EntityReference`, and `Notation`). * Also, add `create_notation`, `create_entity`, and `create_internal_entity` to `dom_impl`. * Implement an options (`ProcessingOptions` and `DOMImplementation::create_document_with_options`) capability to turn on extended processing behaviors. * Fixed some nested borrow issues. ### Version 0.1.2 * Focus on feature completion: * implement all core trait features * implement extended trait features for currently supported traits * unescaping text * refactor `NodeImpl` for extended traits * Unit tests, lot's of unit tests ### Version 0.1.1 * Focus on API, separate the traits from implementation more cleanly. * Better `Display` formatting * Better `append_child` rule support * Have support for namespace resolution * Have support for text escaping on setting values * More examples, fleshing out more of the common methods. * Note, this is NOT YET ready for production usage. ### Version 0.1.0 * Focus on modeling as traits, not all methods actually implemented. * Note, this is NOT YET ready for production usage. ## TODO 1. [More tests required](https://github.com/johnstonskj/rust-xml_dom/issues/4). 1. [More doc test/examples](https://github.com/johnstonskj/rust-xml_dom/issues/5). 1. [Ensure correct notation replacement](https://github.com/johnstonskj/rust-xml_dom/issues/6).