Writing XML

Jacob Carlborg doob at me.com
Sun Feb 6 08:40:55 PST 2011


On 2011-02-06 15:43, Tomek Sowiński wrote:
> While I'm circling the problem of parsing, I took a quick look at writing not to get stuck in analysis-paralysis. Writing XML is pretty independent from parsing and an order of magnitude easier to solve. It was perfect to get myself coding.
>
> These are the guidelines I followed:
>
>   * Memory minimalism: don't force allocating an intermediate node structure just to push a few tags down the wire.
>
>   * Composability: operating on an arbitrary string output range.
>
>   * Robustness: tags should not be left open, even if the routine producing tag interior throws.
>
>   * Simplicity of syntax: resembling real XML if possible.
>
>   * Space efficiency / readability: can write tightly (without indents and newlines) for faster network transfer and, having easy an means for temporary tight writing, for better readability.
>
>   * Ease of use:
>     - automatic to!string of non-string values,
>     - automatic string escaping according to XML standard,
>     - handle nulls: close the tags short (<tag/>), don't write attributes with null values at all.
>
>   * anything else?
>
>
> The new writer meets pretty much all of the above. Here's an example to get a feel of it:
>
> auto books = [
>      Book([Name("Grębosz", "Jerzy")], "Pasja C++", 1999),
>      Book([Name("Navin", "Robert", "N.")], "Mathemetics of Derivatives", 2007),
>      Book([Name("Tokarczuk", "Olga")], "Podróż ludzi Księgi", 1996),
>      Book([Name("Graham", "Ronald", "L."),
>           Name("Knuth", "Donald", "E."),
>           Name("Patashnik", "Oren")], "Matematyka Konkretna", 2008)
> ];
>
> auto outputRange = ... ;
> auto xml = xmlWriter(outputRange);
>
> xml.comment(books.length, " favorite books of mine.");
> foreach (book; books) {
>      xml.book("year", book.year, {
>           foreach (author; book.authors) {
>               xml.tight.authorName({
>                   xml.first(author.first);
>                   xml.middle(author.middle);
>                   xml.last(author.last);
>               });
>           }
>           xml.tight.title(book.title);
>      });
> }
>
> --------------------------------- program output ---------------------------------
>
> <!-- 4 favorite books of mine. -->
> <book year="1999">
>    <authorName><first>Jerzy</first><middle/><last>Grębosz</last></authorName>
>    <title>Pasja C++</title>
> </book>
> <book year="2007">
>    <authorName><first>Robert</first><middle>N.</middle><last>Navin</last></authorName>
>    <title>Mathemetics of Derivatives</title>
> </book>
> <book year="1996">
>    <authorName><first>Olga</first><middle/><last>Tokarczuk</last></authorName>
>    <title>Podróż ludzi Księgi</title>
> </book>
> <book year="2008">
>    <authorName><first>Ronald</first><middle>L.</middle><last>Graham</last></authorName>
>    <authorName><first>Donald</first><middle>E.</middle><last>Knuth</last></authorName>
>    <authorName><first>Oren</first><middle/><last>Patashnik</last></authorName>
>    <title>Matematyka Konkretna</title>
> </book>
>
>
> Questions and comments?

This seems to be like the Ruby "builder" library, which is a library I 
like. This is a perfect candidate for the syntax sugar I've proposed for 
passing delegates to a function after the parameter list.

-- 
/Jacob Carlborg


More information about the Digitalmars-d mailing list