1 {-# LANGUAGE TypeFamilies #-}
3 -- | General XML stuff.
11 import Text.XML.HXT.Core (
29 -- | A typeclass for types which can be converted into an associated
30 -- XML type. The story behind this is long, but basically, we need
31 -- to different types for each XML thingie we're going to import: a
32 -- database type and an XML type. Both Groundhog and HXT are very
33 -- particular about the types that they can use, and there's no way
34 -- to reuse e.g. a type that HXT can pickle in Groundhog. So this
35 -- typeclass gives us a way to get the XML type from the Groundhog
38 -- At first there appears to be an equally-valid approach, getting the
39 -- Groundhog type from the XML one. But Groundhog won't use type family
40 -- instances, so here we are.
43 -- | Each instance a must declare its associated XML type (Xml a)
46 -- | And provide a function for getting an (Xml a) out of an "a."
50 -- | A list of options passed to 'readDocument' when we parse an XML
51 -- document. We don't validate because the DTDs from TSN are
52 -- wrong. As a result, we don't want to keep useless DTDs
53 -- areound. Thus we disable 'withSubstDTDEntities' which, when
54 -- combined with "withValidate no", prevents HXT from trying to read
57 parse_opts :: SysConfigList
59 [ withPreserveComment no,
61 withSubstDTDEntities no,
65 -- | Given a root element name and a file path, return both the
66 -- original unpickled root "object" and the one that was constructed
67 -- by pickled and unpickling the original. This is used in a number
68 -- of XML tests which pickle/unpickle and then make sure that the
69 -- output is the same as the input.
71 -- We return the object instead of an XmlTree (which would save us
72 -- an unpickle call) because otherwise the type of @a@ in the call
73 -- to 'xpickle' would be ambiguous. By returning some @a@s, we allow
74 -- the caller to annotate its type.
76 pickle_unpickle :: XmlPickler a
80 pickle_unpickle root_element filepath = do
81 -- We need to check only the root message element since
82 -- readDocument produces a bunch of other junk.
83 expected <- runX $ arr_getobj
84 actual <- runX $ arr_getobj
90 return (expected, actual)
92 arr_getobj = readDocument parse_opts filepath