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>