Haskell2Xml


Text.XML.HaXml.Haskell2Xml is a library for translating Haskell data from any program into a valid XML document (and back again), by generating a DTD and the appropriate functions to write and write the XML format. In principle, it gives an alternative to the standard Read and Show classes, and allows you to use other standard XML-processing tools on your Haskell datafiles.

Usage. It works rather like the existing Read and Show classes: you must create an instance of the Haskell2Xml 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 Haskell2Xml class. The only remaining thing is to ensure that you import the Text.XML.HaXml.Haskell2Xml module everywhere you use it.

(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 : Haskell2Xml !-}	-- this line is for DrIFT

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     :: Haskell2Xml a => a        -> Document
    fromXml   :: Haskell2Xml a => Document -> a

    readXml   :: Haskell2Xml a => String   -> Maybe a
    showXml   :: Haskell2Xml a => a        -> String

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

    hGetXml   :: Haskell2Xml a => Handle   -> IO a
    hPutXml   :: Haskell2Xml a => Handle   -> a -> IO ()

(These signatures are extremely similar to those in Xml2Haskell - the only difference is the class context, indicating how the types have been derived.)

Do not forget to resolve the overloading 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.)