yxml ~main
XML parsing library, nothrow @nogc, XML subset. Port of yxml.
To use this package, run the following command in your project's root directory:
Manual usage
Put the following dependency into your project's dependences section:
yxml
The yxml DUB package is a simple library that is designed to parse a subset of XML within the constraints of restricted D.
- Allows XML parsing in
nothrow @nogc. - One file, but depends on
numempackage for scoped DOM. - The
yxmlparser from original is fast, however the DOM it constructs isn't particularly efficient. The original library was barebones and intended to be used as SAX parser. But this is a DOM-like API.
Limitations
Not all of XML is supported. The limitations are stronger than the original yxml library.
- Comments are ignored.
- XML Processing Instructions are ignored.
- Can't parse HTML.
- Can't emit XML.
- Not validating, no namespace support.
Usage
📈 Parsing a single value in a file
// EXAMPLE: the file has this shape.
// ------------------------------------------------
// <?xml version="1.0" encoding="UTF-8"?>
// <results>
// <metric value="5.8" />
// </results>
// ------------------------------------------------
// Note: This example assumes you can use the GC for error reporting,
// but `yxml` doesn't strictly require it.
void parseMyXMLData(const(char)[] xmlData)
{
import yxml;
// Parse a whole XML file, builds a DOM.
XmlDocument doc;
doc.parse(xmlData);
// Parsing error is dealt with error codes.
if (doc.isError)
{
const(char)[] message = doc.errorMessage;
// ...do something with the error,
// such as throwing if you can:
throw new Exception(message.idup);
}
XmlElement root = doc.root;
if (root.tagName != "results")
throw new Exception("expected <results> as root XML anchor");
foreach(e; root.getChildrenByTagName("metric"))
{
if (!e.hasAttribute("value"))
throw new Exception(`expected attribute "value" in <metric>`);
return to!double(e.getAttribute("value")); // return first seen
}
throw new Exception("expected <metric>");
}
📈 Iterate children of a XmlElement
childNodesreturn range that iterates on children, who are allXmlElementthemselves.childElementCountreturn the number of children.
void parseCustomers(XmlElement parent)
{
// Iterate on the child nodes of `parent`
foreach(XmlElement node; parent.childNodes)
{
writeln(node.tagName); // Display <tag> name.
writeln(node.textContent); // Display its content and that of its children
}
}
🧑💼 **Pro XML parsing tip:** Use `.dup` or `.idup` to make copies of tag names of text content, because the lifetime of the DOM is the one of the `XmlDocument`. You don't want your characters string to disappear over you, right?
📈 Find a child with given tag name
- Use
XmlElement.firstChildByTagName(const(char)[] tagName)for first matching element.
void parseCustomer(XmlElement customer)
{
XmlElement name = customer.firstChildByTagName("name");
if (name is null)
throw new Exception("<customer> has no <name>!");
}
🧑💼 **Pro XML parsing tip:** You can be even clearer in intent by using `.hasChildWithTagName`.
📈 Iterate children of a XmlElement by tag name
getChildrenByTagNamereturn range that iterates on direct children that match a given tag name, no recursion.
void parseSupportDeskFile(XmlElement parent)
{
foreach(XmlElement customer; parent.getChildrenByTagName("customer"))
{
// Do something with customer
}
}
🧑💼 **Pro XML parsing tip:** Use .array to get a slice rather than a range.
import std.array; XmlElement[] elems = node.getChildrenByTagName("customer").array; writeln("%s customers found.", elems.length);
📈 Get a single attribute
All these 3 examples are equivalent:
void parseCustomers(XmlElement node)
{
// null if such an attribute doesn't exist
const(char)[] blurb = node.getAttribute("blurb");
if (!blurb)
throw new Exception(`no "blurb" attribute!`);
}
void parseCustomers(XmlElement node)
{
const(char)[] blurb = null;
if (node.hasAttribute("blurb"))
{
XmlAttr attr = node.getAttributeNode("blurb");
blurb = attr.value();
}
if (!blurb)
throw new Exception(`no "blurb" attribute!`);
}
void parseCustomers(XmlElement node)
{
const(char)[] blurb = null;
// Iterate on all attributes
foreach(attr; node.attributes())
{
if (attr.name == "blurb")
blurb = attr.value;
}
if (!blurb)
throw new Exception(`no "blurb" attribute!`);
}
- ~main released 10 months ago
- AuburnSounds/yxml
- MIT
- Dependencies:
- dplug:core
- Versions:
-
Show all 13 versions0.1.7 2025-Jan-05 0.1.6 2025-Jan-05 0.1.5 2024-Oct-07 0.1.4 2024-Aug-05 0.1.3 2024-Feb-14 - Download Stats:
-
-
0 downloads today
-
0 downloads this week
-
25 downloads this month
-
150 downloads total
-
- Score:
- 0.8
- Short URL:
- yxml.dub.pm