Data formats

XML

XML read as nested maps, the texts and attributes of the elements you name, and text escaped for XML.

Version 1.0.0 · 4 functions · 1 crate

#xml#import#sitemaps#soap

Functions

What use xml.qwer gives a program, with the types Quillo sees. To take only some, or under other names: use xml_parse, xml_texts from xml (Quillo 0.6).

xml_parse(text: str) → anyor an error

XML text as nested maps: { tag, attrs, text, children } for each element (namespaces dropped from names). DTDs are refused.

xml_texts(text: str, tag: str) → listor an error

The text of every element named tag, in document order: xml_texts(feed, "title").

xml_attrs(text: str, tag: str, attr: str) → listor an error

An attribute of every element named tag that has it: xml_attrs(svg, "path", "d").

xml_escape(text: str) → str

Text made safe to put inside XML: &, <, >, " and ' escaped.

Get it

$ quillo install xml               # xml.qwer into this folder$ quillo install xml --example     # and its example, xml.qwe

Or with curl:

$ curl -O https://quillolang.org/plugins/files/xml.qwer$ curl -O https://quillolang.org/plugins/files/xml.qwe

Then, in your program, all of it or only what you call:

main.qwe
use xml.qweruse xml_parse, xml_texts from xml      // Quillo 0.6: only these

It uses this crate, which cargo fetches the first time the plugin is built:

[dependencies]
roxmltree = "0.20"

Example

xml.qwe
// Reads a sitemap and an order in XML.////   quillo run xml.qwe      then open http://localhost:8080/urlsuse "xml.qwer"let sitemap = `<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">  <url><loc>https://quillolang.org/</loc></url>  <url><loc>https://quillolang.org/docs/</loc><lastmod>2026-10-29</lastmod></url></urlset>`route GET /urls = xml_texts(sitemap, "loc")?route GET /order = xml_parse(`<order id="42"><item sku="A1" qty="2">Pen</item><item sku="B7" qty="1">Ink</item></order>`)?
$ quillo run xml.qwe$ curl 'localhost:8080/urls'$ curl 'localhost:8080/order'

Source

xml.qwer
//! XML read as values: feeds from partners, SOAP answers, sitemaps, invoices (UBL), SVG.//! version: 1.0.0//!//! [dependencies]//! roxmltree = "0.20"use serde_json::{json, Map, Value};fn element(n: roxmltree::Node) -> Value {    let attrs: Map<String, Value> = n.attributes().map(|a| (a.name().to_string(), Value::String(a.value().to_string()))).collect();    let children: Vec<Value> = n.children().filter(|c| c.is_element()).map(element).collect();    let text: String = n.children().filter(|c| c.is_text()).filter_map(|c| c.text()).collect::<String>();    json!({ "tag": n.tag_name().name(), "attrs": attrs, "text": text.trim(), "children": children })}fn doc(text: &str) -> Result<roxmltree::Document<'_>, String> {    roxmltree::Document::parse_with_options(text, roxmltree::ParsingOptions { allow_dtd: false, ..Default::default() }).map_err(|e| e.to_string())}/// XML text as nested maps: `{ tag, attrs, text, children }` for each element (namespaces dropped from names). DTDs are refused.pub fn xml_parse(text: &str) -> Result<Value, String> {    Ok(element(doc(text)?.root_element()))}/// The text of every element named `tag`, in document order: `xml_texts(feed, "title")`.pub fn xml_texts(text: &str, tag: &str) -> Result<Vec<String>, String> {    Ok(doc(text)?.descendants().filter(|n| n.is_element() && n.tag_name().name() == tag)        .map(|n| n.descendants().filter(|c| c.is_text()).filter_map(|c| c.text()).collect::<String>().trim().to_string()).collect())}/// An attribute of every element named `tag` that has it: `xml_attrs(svg, "path", "d")`.pub fn xml_attrs(text: &str, tag: &str, attr: &str) -> Result<Vec<String>, String> {    Ok(doc(text)?.descendants().filter(|n| n.is_element() && n.tag_name().name() == tag)        .filter_map(|n| n.attribute(attr).map(str::to_string)).collect())}/// Text made safe to put inside XML: `&`, `<`, `>`, `"` and `'` escaped.pub fn xml_escape(text: &str) -> String {    text.replace('&', "&amp;").replace('<', "&lt;").replace('>', "&gt;").replace('"', "&quot;").replace('\'', "&apos;")}
Thread
76Useful? Like it, or add to its thread below.

Thread 0 posts

On XML: questions, tips, corrections, and code that uses it.

No posts yet. The first one opens the thread.