xml
Read and write XML. xml.parse(text) gives a node map {tag, attrs, children, text} with find(path) and find_all(path) using a small XPath subset ("item", "a/b", ".//name", "item[@id='3']", "item[2]"). xml.stringify(node) writes a node (or a plain map with those keys) back out. Documents with a DOCTYPE are rejected, which protects against entity-expansion attacks.
import xml
Example
import xml
let doc = xml.parse(
"<scan host=\"192.0.2.5\"><port id=\"22\" state=\"open\"/><port id=\"80\" state=\"closed\"/></scan>",
)
say(doc.tag, doc.attrs.host)
for p in doc.find_all("port") {
say(p.attrs.id, p.attrs.state)
}
say(xml.stringify(xml.node("note", {"by": "Tanisha"}, ["checked"])))
Functions
parse(text)
returns nodeRead XML text into a node: {"tag", "attrs" (map), "children" (list of nodes), "text"} plus find(path), find_all(path), value(path), attr(name), all_text(). A DOCTYPE is refused.
Visualizehow xml.parse works
xml.parse("<feed><item id=\"1\">Hello</item><item id=\"2\">Bye</item></feed>") gives {"tag": "feed", "attrs": {}, "children": [{"tag": "item", "attrs": {"id": "1"}, "children…
Real result: worked out by running this example with TB while the site was built.
stringify(node, options?)
returns textTurn a node into XML text. Text is escaped for you. The node can come from parse, or be a plain map: {"tag": "item", "attrs": {...}, "children": [...], "text": "..."}.
Options
indentthe indent text (default: " "). false puts it all on one line.declarationtrue adds the <?xml ...?> header.
Visualizehow xml.stringify works
xml.stringify(xml.node("feed", {}, [xml.node("item", {"id": 1}, ["Hello"])]), {}) gives "<feed>\n <item id=\"1\">Hello</item>\n</feed>"xml.stringify(xml.node("feed", {}, [xml.node("item", {"id": 1}, ["Hello"])]), {"indent": false}) gives "<feed><item id=\"1\">Hello</item></feed>"xml.stringify(xml.node("feed", {}, [xml.node("item", {"id": 1}, ["Hello"])]), {"declaration": true}) gives "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<feed>\n <item id=\"1\">Hello</item>\n</fee…
Real result: worked out by running this example with TB while the site was built.
read(path)
returns nodeRead an XML file (see parse).
Visualizehow xml.read works
xml.read("feed.xml").find_all("item").map(n => n.text) gives ["Hello", "Bye"]
Real result: worked out by running this example with TB while the site was built.
write(path, node, options?)
Save a node as an XML file (with the <?xml ?> header).
Visualizehow xml.write works
xml.write("note.xml", xml.node("note", {"lang": "en"}, ["Hi & bye"]))
Real result: worked out by running this example with TB while the site was built.
node(tag, attrs?, children?)
returns mapMake a node to build documents with: xml.node("item", {"id": 1}, ["Hello"]). children may hold nodes and plain text.
Visualizehow xml.node works
xml.node("item", {"id": 1}, ["Hello"]) gives {"tag": "item", "attrs": {"id": 1}, "children": [], "text": "Hello"}
Real result: worked out by running this example with TB while the site was built.
escape(text)
returns textText made safe inside XML.
Changes
- < becomes <
- > becomes >
- & becomes &
Visualizehow xml.escape works
xml.escape("5 < 7 & 9 > 3") gives "5 < 7 & 9 > 3"
Real result: worked out by running this example with TB while the site was built.
quote_attr(text)
returns textText quoted as an attribute value, like "a & b" with its quotes.
Visualizehow xml.quote_attr works
xml.quote_attr("R&D \"lab\"") gives "'R&D \"lab\"'"
Real result: worked out by running this example with TB while the site was built.
is_node(x)
returns boolTrue if x looks like an XML node (a map with a text "tag").
Visualizehow xml.is_node works
xml.is_node(xml.node("a")) gives truexml.is_node({"tag": "item"}) gives truexml.is_node("<a/>") gives falsexml.is_node({"name": "x"}) gives false
Real result: worked out by running this example with TB while the site was built.