1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
/*! ![build](https://github.com/webern/exile/workflows/exile%20ci/badge.svg) `exile` is a Rust library for reading and writing XML. The goal, at least initially, is to provide an abstract syntax tree of an XML file. As such, this is a Exile is a dom parser and loads the complete contents of the document into memory. Currently supported: - Attributes - CDATA Sections - Comment Parsing - Elements - Processing Instructions - Text Nodes - UTF-8 - Whitespace Normalization Not Supported: - Doctypes - Entities - Entity References - Other Encodings - Whitesace Preservation: All text nodes are treated as if whitespace `collapse` were in-effect. # Example Parsing XML looks like this. ``` let xml = r#" <root> <thing name="foo"/> <thing>bar</thing> </root> "#; let doc = exile::parse(xml).unwrap(); for child in doc.root().children() { println!("element name: {}", child.name()); if let Some(attribute) = child.attribute("name") { println!("name attribute: {}", attribute); } } // we can create an index of elements let index = doc.index(); // the element at index 2 is <thing>bar</thing> let thing = index.element(2).unwrap(); // the parent of index 2 is <root> let root = index.parent(&thing).unwrap(); assert_eq!("bar", thing.text().unwrap()); assert_eq!("root", root.name()); ``` Authoring XML looks like this. ``` use exile::{Document, Element, Node}; let mut root = Element::from_name("my_root"); root.add_attribute("foo", "bar"); let mut child = Element::from_name("my_child"); child.add_text("Hello World!"); root.add_child(child); let doc = Document::from_root(root); println!("{}", doc.to_string()); ``` The above program prints: ```xml <my_root foo="bar"> <my_child>Hello World!</my_child> </my_root> ``` */ #![deny(rust_2018_idioms)] #![deny(missing_docs, unused_imports)] use std::path::Path; pub use crate::parser::ParseError; pub use crate::xdoc::{ Declaration, Document, Element, Encoding, Index, Misc, Node, Pi, Version, WriteOpts, }; pub use crate::xmlns::{Namespace, NcName, NsErr, QName}; /// The `error` module defines the error types for this library. #[macro_use] mod macros; mod constants; pub mod error; pub mod parser; mod xdoc; mod xmlns; /// Parse an XML file held in string contents. pub fn parse<S: AsRef<str>>(xml: S) -> crate::error::Result<Document> { parser::document_from_string(xml) } /// Load a document from a file. pub fn load<P: AsRef<Path>>(path: P) -> crate::error::Result<Document> { parser::document_from_file(path) } // TODO - streaming https://github.com/webern/exile/issues/20 #[test] fn simple_document_test() { let xml = r#" <r> <a b="c"/> </r> "#; let doc = parse(xml).unwrap(); let root = doc.root(); assert_eq!("r", root.name()); assert_eq!(1, root.nodes_len()); let child = root.first_node().unwrap(); if let Node::Element(element) = child { assert_eq!("a", element.name()); let attribute_value = element.attribute("b").unwrap(); assert_eq!("c", attribute_value); } else { panic!("expected element but found a different type of node") } }