HaXml: Haskell and XML

## XmlContent

Text.XML.HaXml.XmlContent is a library/class for translating Haskell data from any program into a valid XML document (and back again). In principle, it gives an alternative to the standard Read and Show classes, allowing you to use fully typed data in Haskell rather than the generic XML tree representation.

Usage 1. It works rather like the existing Read and Show classes: you must create an instance of the XmlContent class for every datatype you wish to use for I/O. However, because this class is not a standard one, no Haskell compilers support the `deriving` clause for it yet. Fear not! There is a pre-processor tool called DrIFT which derives class instances automatically. We have extended DrIFT's ruleset to include the XmlContent class.

(Please note that DrIFT is sometimes a bit fragile when parsing Haskell sources - it occasionally fails to recognise the derive command. We have found a workaround: isolate just the `data` type declarations that are of interest, and run DrIFT on them separately.) The syntax required is like this example:

      data MyType a = A a | B String deriving (Eq, Show)
          {-! derive : XmlContent !-}	-- this line is for DrIFT

Usage 2. Alternatively, you may start by having XML documents with a standard DTD defined elsewhere, e.g. SVG, SMIL, MathML etc. You can convert the DTD into an isomorphic collection of Haskell datatypes, including all the requisite instances of XmlContent, with the tool DtdToHaskell included in HaXml.

Usage 3. Finally, you may have a document type definition expressed in XML Schema rather than a DTD. Use the XsdToHaskell tool in this case, to convert the Schema into an isomorphic collection of Haskell datatypes, including all the requisite instances of XmlContent.

API To read and write Haskell data values as XML files, you have a choice of function pairs: `toXML/fromXML` convert between typed Haskell values and the generic internal XML representation; `showXml/readXml` convert to/from Strings; `fWriteXml/fReadXml` convert to/from named files; `hPutXml/hGetXml` convert to/from file Handles.

        toXml     :: XmlContent a => Bool -> a  -> Document ()
        fromXml   :: XmlContent a => Document Posn -> Either String a

        readXml   :: XmlContent a => String        -> Either String a
        showXml   :: XmlContent a => Bool -> a  -> String

        fReadXml  :: XmlContent a => FilePath -> IO a
        fWriteXml :: XmlContent a => FilePath -> a -> IO ()

        hGetXml   :: XmlContent a => Handle   -> IO a
        hPutXml   :: XmlContent a => Handle   -> Bool -> a -> IO ()

Because parsing the document might fail, some of these functions return an Either String, where the string contains an error message. Boolean arguments to output-writing functions indicate whether or not to include a DTD in the output.

Particularly when you read from XML, you may need to resolve the overloading of the result value in one of the usual ways (e.g. by implicit context at point of use, by explicit type signatures on values, use value as an argument to a function with an explicit signature, use ``asTypeOf``, etc.)