3 releases (stable)
1.0.1 | Oct 12, 2024 |
---|---|
1.0.0 | May 31, 2024 |
0.0.0 | May 27, 2024 |
#1017 in Configuration
120KB
2K
SLoC
KISS-XML: Keep It Super Simple XML
This Rust library provides an easy-to-use Document Object Model (DOM) for reading and writing XML files. Unlike many other XML parsers, KISS-XML simply parses the given XML to a full DOM, which you can then modify and serialize back to XML. No schemas or looping required.
What's included:
KISS-XML provides the basics for XML documents, including:
- Parse XML files and strings to a DOM
- XML elements, text, and comments
- DOM is mutable and can be saved as a string and to files
- XML namespaces (with and without prefixes)
- CDATA
- Easy to use
What's NOT included:
- Schema handling
- Document type declarations (DTDs will be preserved but not interpreted)
- Parsing character encodings other than UTF-8
- Typed XML data (eg integer attribute values)
- Performance optimizations (prioritizing easy-to-use over fast)
If you need any of the above excluded XML features, then this library is too simple for your needs. Try another XML parsing crate instead.
Quickstart Guide
First, add the following to your Cargo.toml file:
kiss_xml = "1"
Then to parse an XML file, all you need to do is call the
kiss_xml::parse_filepath(...)
function, like this:
fn main() -> Result<(), kiss_xml::errors::KissXmlError> {
use kiss_xml;
let doc = kiss_xml::parse_filepath("some-file.xml")?;
println!("{}", doc.to_string());
Ok(())
}
The XML content will be converted into a Document Object Model (DOM) with a
single root element. A DOM is a tree-like data structure made up of XML Element,
Text, and Comment nodes. You can explore the DOM element-by-element with the
.elements_by_name(&str)
and .first_element_by_name(&str)
methods, scan the
children of an element with the .children()
and .child_elements()
methods, or do a recursive search
using the .search(...)
and .search_*(...)
methods.
For example:
fn main() -> Result<(), kiss_xml::errors::KissXmlError> {
use kiss_xml;
use kiss_xml::dom::*;
use kiss_xml::errors::*;
let xml = r#"<?xml version="1.0" encoding="UTF-8"?>
<config>
<name>My Settings</name>
<sound>
<property name="volume" value="11" />
<property name="mixer" value="standard" />
</sound>
</config>
"#;
// parse XML to a document object model (DOM)
let dom = kiss_xml::parse_str(xml)?;
// print all sound properties
let properties = dom.root_element()
.first_element_by_name("sound")?
.elements_by_name("property");
for prop in properties {
println!(
"{} = {}",
prop.get_attr("name").ok_or(DoesNotExistError::default())?,
prop.get_attr("value").ok_or(DoesNotExistError::default())?
);
}
// print children of the root element
for e in dom.root_element().child_elements() {
println!("child element <{}>", e.name())
}
// print all elements
for e in dom.root_element().search_elements(|_| true) {
println!("found element <{}>", e.name())
}
Ok(())
}
To modify the DOM, use the .*_mut(...)
methods to get mutable references to
the elements, and you can convert the DOM to a string with the .to_string()
method or write it to a file with .write_to_filepath(...)
.
For example:
fn main() -> Result<(), kiss_xml::errors::KissXmlError> {
use kiss_xml;
use kiss_xml::dom::*;
use kiss_xml::errors::*;
// make a DOM from scratch
let mut doc = Document::new(Element::new_from_name("politicians")?);
doc.root_element_mut().insert(0, Element::new_with_text("person", "John Adams")?);
doc.root_element_mut().append(Element::new_with_text("person", "Hillary Clinton")?);
doc.root_element_mut().append(Element::new_with_text("person", "Jimmy John")?);
doc.root_element_mut().append(Element::new_with_text("person", "Nanny No-Name")?);
// remove element by index
let _removed_element = doc.root_element_mut().remove_element(3)?;
// remove element(s) by use of a predicate function
let _num_removed = doc.root_element_mut().remove_elements(|e| e.text() == "Jimmy John");
// print first element content
println!("First politician: {}", doc.root_element().first_element_by_name("person")?.text());
// write to file
doc.write_to_filepath("tests/politics.xml");
Ok(())
}
For more details and examples, see the documentation.
How to Contribute
Found a bug? Want to add a new feature? Great! Here's what to do:
First, create an issue on the official KISS-XML GitHub page. Make sure that your issue description includes examples and use-cases.
Next, create one or more unit tests that fails unless the bug-fix/feature is correctly implemented. The unit tests can be proposed in your issue description or you can fork the KISS-XML repo and add them to the file tests/issues.rs
. Make sure all test functions start with "test_issue_##" and contain a link to the GitHub issue thread in the description.
Finally, if you've implemented it yourself in a fork, create a pull request from your fork into the staging
branch (PRs to main
will be rejected).
Thank you!
License
This library is open source, licensed under the MIT License. You may use it as-is or with modification, without any limitations.
Dependencies
~2.2–3MB
~54K SLoC