A simple XML parser and renderer with support for streaming

root

XML Pardner

This is an XML parser and renderer with support for streaming.

Beside being able to specify parsers and renderers, pardner also allows a number of combinators that allow simultaneous definition of both an XML parser and renderer using the same code. This reduces code size and ensures that parsing and rendering always are in sync.

Installation

The xml-pardner package is most easily installed from Hackage using Cabal using the commands

cabal update
cabal install xml-pardner

Alternatively, using Cabal it is possible to install xml-pardner directly from the project directory, for example, to check out the project from its Darcs repository and installing it you may run the following commands:

darcs get http://hub.darcs.net/rycee/xml-pardner
cd xml-pardner
cabal install

Usage

As mentioned above, using xml-pardner you are able to specify XML parsers, renderers, or both at the same time. Which one if most suitable depends on the application. If the primary objective is to parse XML then the parsing interface offered by xml-pardner is more convenient to work with than specifying both a parser and a renderer simultaneously.

For example, consider a simple application keeping track of a music collection. It may represent a collection as a list of albums with artist, title, and track, i.e., something like

type Artist = Text
type Title = Text
data Track = Track Title deriving (Show)
data Album = Album Artist Title [Track] deriving (Show)
type Collection = [Album]

For these data types we may wish to read and write an XML representation of a music collection, for example, the album Defrag by Binärpilot and the album Kind of Blue by Miles Davis. The following program gives exactly that:

import Text.XML.Pardner

type Artist = Text
type Title = Text
data Track = Track Title deriving (Eq, Show)
data Album = Album Artist Title [Track] deriving (Eq, Show)
type Collection = [Album]

music = [ Album "Binärpilot" "Defrag"
            [ Track "Goof"
            , Track "Sandjorda"
            , Track "Widibf"
            , Track "Fuayfsilfm"
            ]
        , Album "Miles Davis" "Kind of Blue"
            [ Track "So What"
            , Track "Freddie Freeloader"
            , Track "Blue in Green"
            , Track "All Blues"
            , Track "Flamenco Sketches"
            ]
        ]

pTrack = tag "track" $ iso (\title -> Track title) (\(Track title) -> title) content
pAlbum = tag "album" $ iso (\((artist, title), tracks) -> Album artist title tracks)
                           (\(Album artist title tracks) -> ((artist, title), tracks))
                           (attr "artist" <&> attr "title" <&> many pTrack)
pCollection = document $ tag "collection" $ many pAlbum

renderCollection = renderToText (def { rsPretty = True }) pCollection music

When run, renderCollection will return the following XML:

<?xml version="1.0" encoding="UTF-8"?>
<collection>
  <album artist="Binärpilot" title="Defrag">
    <track>Goof</track>
    <track>Sandjorda</track>
    <track>Widibf</track>
    <track>Fuayfsilfm</track>
  </album>
  <album artist="Miles Davis" title="Kind of Blue">
    <track>So What</track>
    <track>Freddie Freeloader</track>
    <track>Blue in Green</track>
    <track>All Blues</track>
    <track>Flamenco Sketches</track>
  </album>
</collection>