[Haskell-cafe] XmlSerializer.deserialize?
Hugh Perkins
hughperkins at gmail.com
Sun Jul 1 17:58:47 EDT 2007
Well, figured out a solution to parsing xml. It's not really pretty, but it
works.
Basically we just convert the incoming xml into a gread compatible format
then use gread :-D
If someone has a more elegant solution, please let me know.
module ParseXml
where
import IO
import Char
import List
import Maybe
import Data.Generics hiding (Unit)
import Text.XML.HXT.Arrow hiding (when)
data Config = Config{ name :: String, age :: Int }
--data Config = Config{ age :: Int }
deriving( Data, Show, Typeable, Ord, Eq, Read )
createConfig = Config "qsdfqsdf" 3
--createConfig = Config 3
gshow' :: Data a => a -> String
gshow' t = fromMaybe (showConstr(toConstr t)) (cast t)
-- helper function from http://www.defmacro.org/ramblings/haskell-web.html
introspectData :: Data a => a -> [(String, String)]
introspectData a = zip fields (gmapQ gshow' a)
where fields = constrFields $ toConstr a
-- function to create xml string from single-layer Haskell data type
xmlSerialize object = "<" ++ show(toConstr object) ++ ">" ++
foldr (\(a,b) x -> x ++ "<" ++ a ++ ">" ++ b ++ "</" ++ a ++ ">") "" (
introspectData object )
++ "</" ++ show(toConstr object) ++ ">"
-- parse xml to HXT tree, and obtain the value of node "fieldname"
-- returns a string
getValue xml fieldname | length(resultlist) > 0 = Just (head resultlist)
| otherwise = Nothing
where resultlist = (runLA ( constA xml >>> xread >>> deep ( hasName
fieldname ) >>> getChildren >>> getText ))[]
-- parse templateobject to get list of field names
-- apply these to xml to get list of values
-- return (fieldnames list, value list)
xmlToGShowFormat :: Data a => String -> a -> String
xmlToGShowFormat xml templateobject =
go
where mainconstructorname = (showConstr $ toConstr templateobject)
fields = constrFields $ toConstr templateobject
values = map ( \fieldname -> getValue xml fieldname ) fields
datatypes = gmapQ (dataTypeOf) templateobject
constrs = gmapQ (toConstr) templateobject
datatypereps = gmapQ (dataTypeRep . dataTypeOf) templateobject
fieldtogshowformat (value,datatyperep) = case datatyperep of
IntRep -> "(" ++ fromJust value ++ ")"
_ -> show(fromJust value)
formattedfieldlist = map (fieldtogshowformat) (zip values
datatypereps)
go = "(" ++ mainconstructorname ++ " " ++ (concat $ intersperse " "
formattedfieldlist ) ++ ")"
xmlDeserialize xml templateobject = fst $ head $ gread( xmlToGShowFormat xml
templateobject)
dotest = xmlDeserialize (xmlSerialize createConfig) createConfig :: Config
dotest' = xmlDeserialize ("<Config><age>12</age><name>test
name!</name></Config>") createConfig :: Config
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20070701/d23c28d9/attachment.htm
More information about the Haskell-Cafe
mailing list