{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, FunctionalDependencies #-}
module Text.XML.HXT.DOM.XmlNode
( module Text.XML.HXT.DOM.XmlNode
, module Data.Tree.Class
, module Data.Tree.NTree.TypeDefs
)
where
import Control.Monad
import Control.FlatSeq
import Data.Function ( on )
import Data.Maybe ( fromMaybe
, fromJust
)
import Data.Tree.Class
import Data.Tree.NTree.TypeDefs
import Text.XML.HXT.DOM.Interface
class XmlNode a where
isText :: a -> Bool
isBlob :: a -> Bool
isCharRef :: a -> Bool
isEntityRef :: a -> Bool
isCmt :: a -> Bool
isCdata :: a -> Bool
isPi :: a -> Bool
isElem :: a -> Bool
isRoot :: a -> Bool
isDTD :: a -> Bool
isAttr :: a -> Bool
isError :: a -> Bool
mkText :: String -> a
mkBlob :: Blob -> a
mkCharRef :: Int -> a
mkEntityRef :: String -> a
mkCmt :: String -> a
mkCdata :: String -> a
mkPi :: QName -> XmlTrees -> a
mkError :: Int -> String -> a
getText :: a -> Maybe String
getBlob :: a -> Maybe Blob
getCharRef :: a -> Maybe Int
getEntityRef :: a -> Maybe String
getCmt :: a -> Maybe String
getCdata :: a -> Maybe String
getPiName :: a -> Maybe QName
getPiContent :: a -> Maybe XmlTrees
getElemName :: a -> Maybe QName
getAttrl :: a -> Maybe XmlTrees
getDTDPart :: a -> Maybe DTDElem
getDTDAttrl :: a -> Maybe Attributes
getAttrName :: a -> Maybe QName
getErrorLevel :: a -> Maybe Int
getErrorMsg :: a -> Maybe String
getName :: a -> Maybe QName
getQualifiedName :: a -> Maybe String
getUniversalName :: a -> Maybe String
getUniversalUri :: a -> Maybe String
getLocalPart :: a -> Maybe String
getNamePrefix :: a -> Maybe String
getNamespaceUri :: a -> Maybe String
changeText :: (String -> String) -> a -> a
changeBlob :: (Blob -> Blob) -> a -> a
changeCmt :: (String -> String) -> a -> a
changeName :: (QName -> QName) -> a -> a
changeElemName :: (QName -> QName) -> a -> a
changeAttrl :: (XmlTrees -> XmlTrees) -> a -> a
changeAttrName :: (QName -> QName) -> a -> a
changePiName :: (QName -> QName) -> a -> a
changeDTDAttrl :: (Attributes -> Attributes) -> a -> a
setText :: String -> a -> a
setBlob :: Blob -> a -> a
setCmt :: String -> a -> a
setName :: QName -> a -> a
setElemName :: QName -> a -> a
setElemAttrl :: XmlTrees -> a -> a
setAttrName :: QName -> a -> a
setPiName :: QName -> a -> a
setDTDAttrl :: Attributes -> a -> a
getName n = getElemName n `mplus` getAttrName n `mplus` getPiName n
getQualifiedName n = getName n >>= return . qualifiedName
getUniversalName n = getName n >>= return . universalName
getUniversalUri n = getName n >>= return . universalUri
getLocalPart n = getName n >>= return . localPart
getNamePrefix n = getName n >>= return . namePrefix
getNamespaceUri n = getName n >>= return . namespaceUri
setText = changeText . const
setBlob = changeBlob . const
setCmt = changeCmt . const
setName = changeName . const
setElemName = changeElemName . const
setElemAttrl = changeAttrl . const
setAttrName = changeAttrName . const
setPiName = changePiName . const
setDTDAttrl = changeDTDAttrl . const
instance XmlNode XNode where
isText (XText _) = True
isText (XBlob _) = True
isText _ = False
{-# INLINE isText #-}
isBlob (XBlob _) = True
isBlob _ = False
{-# INLINE isBlob #-}
isCharRef (XCharRef _) = True
isCharRef _ = False
{-# INLINE isCharRef #-}
isEntityRef (XEntityRef _) = True
isEntityRef _ = False
{-# INLINE isEntityRef #-}
isCmt (XCmt _) = True
isCmt _ = False
{-# INLINE isCmt #-}
isCdata (XCdata _) = True
isCdata _ = False
{-# INLINE isCdata #-}
isPi (XPi _ _) = True
isPi _ = False
{-# INLINE isPi #-}
isElem (XTag _ _) = True
isElem _ = False
{-# INLINE isElem #-}
isRoot t = isElem t
&&
fromMaybe "" (getQualifiedName t) == t_root
isDTD (XDTD _ _) = True
isDTD _ = False
{-# INLINE isDTD #-}
isAttr (XAttr _) = True
isAttr _ = False
{-# INLINE isAttr #-}
isError (XError _ _) = True
isError _ = False
{-# INLINE isError #-}
mkText = XText
{-# INLINE mkText #-}
mkBlob = XBlob
{-# INLINE mkBlob #-}
mkCharRef = XCharRef
{-# INLINE mkCharRef #-}
mkEntityRef = XEntityRef
{-# INLINE mkEntityRef #-}
mkCmt = XCmt
{-# INLINE mkCmt #-}
mkCdata = XCdata
{-# INLINE mkCdata #-}
mkPi = XPi
{-# INLINE mkPi #-}
mkError = XError
{-# INLINE mkError #-}
getText (XText t) = Just t
getText (XBlob b) = Just . blobToString $ b
getText _ = Nothing
{-# INLINE getText #-}
getBlob (XBlob b) = Just b
getBlob _ = Nothing
{-# INLINE getBlob #-}
getCharRef (XCharRef c) = Just c
getCharRef _ = Nothing
{-# INLINE getCharRef #-}
getEntityRef (XEntityRef e) = Just e
getEntityRef _ = Nothing
{-# INLINE getEntityRef #-}
getCmt (XCmt c) = Just c
getCmt _ = Nothing
{-# INLINE getCmt #-}
getCdata (XCdata d) = Just d
getCdata _ = Nothing
{-# INLINE getCdata #-}
getPiName (XPi n _) = Just n
getPiName _ = Nothing
{-# INLINE getPiName #-}
getPiContent (XPi _ c) = Just c
getPiContent _ = Nothing
{-# INLINE getPiContent #-}
getElemName (XTag n _) = Just n
getElemName _ = Nothing
{-# INLINE getElemName #-}
getAttrl (XTag _ al) = Just al
getAttrl (XPi _ al) = Just al
getAttrl _ = Nothing
{-# INLINE getAttrl #-}
getDTDPart (XDTD p _) = Just p
getDTDPart _ = Nothing
{-# INLINE getDTDPart #-}
getDTDAttrl (XDTD _ al) = Just al
getDTDAttrl _ = Nothing
{-# INLINE getDTDAttrl #-}
getAttrName (XAttr n) = Just n
getAttrName _ = Nothing
{-# INLINE getAttrName #-}
getErrorLevel (XError l _) = Just l
getErrorLevel _ = Nothing
{-# INLINE getErrorLevel #-}
getErrorMsg (XError _ m) = Just m
getErrorMsg _ = Nothing
{-# INLINE getErrorMsg #-}
changeText cf (XText t) = XText . cf $ t
changeText cf (XBlob b) = XText . cf . blobToString $ b
changeText _ _ = error "changeText undefined"
{-# INLINE changeText #-}
changeBlob cf (XBlob b) = XBlob . cf $ b
changeBlob _ _ = error "changeBlob undefined"
{-# INLINE changeBlob #-}
changeCmt cf (XCmt c) = XCmt . cf $ c
changeCmt _ _ = error "changeCmt undefined"
{-# INLINE changeCmt #-}
changeName cf (XTag n al) = XTag (cf n) al
changeName cf (XAttr n) = XAttr . cf $ n
changeName cf (XPi n al) = XPi (cf n) al
changeName _ _ = error "changeName undefined"
{-# INLINE changeName #-}
changeElemName cf (XTag n al) = XTag (cf n) al
changeElemName _ _ = error "changeElemName undefined"
{-# INLINE changeElemName #-}
changeAttrl cf (XTag n al) = XTag n (cf al)
changeAttrl cf (XPi n al) = XPi n (cf al)
changeAttrl _ _ = error "changeAttrl undefined"
{-# INLINE changeAttrl #-}
changeAttrName cf (XAttr n) = XAttr . cf $ n
changeAttrName _ _ = error "changeAttrName undefined"
{-# INLINE changeAttrName #-}
changePiName cf (XPi n al) = XPi (cf n) al
changePiName _ _ = error "changePiName undefined"
{-# INLINE changePiName #-}
changeDTDAttrl cf (XDTD p al) = XDTD p (cf al)
changeDTDAttrl _ _ = error "changeDTDAttrl undefined"
{-# INLINE changeDTDAttrl #-}
mkElementNode :: QName -> XmlTrees -> XNode
mkElementNode = XTag
{-# INLINE mkElementNode #-}
mkAttrNode :: QName -> XNode
mkAttrNode = XAttr
{-# INLINE mkAttrNode #-}
mkDTDNode :: DTDElem -> Attributes -> XNode
mkDTDNode = XDTD
{-# INLINE mkDTDNode #-}
instance (XmlNode a, Tree t) => XmlNode (t a) where
isText = isText . getNode
{-# INLINE isText #-}
isBlob = isBlob . getNode
{-# INLINE isBlob #-}
isCharRef = isCharRef . getNode
{-# INLINE isCharRef #-}
isEntityRef = isEntityRef . getNode
{-# INLINE isEntityRef #-}
isCmt = isCmt . getNode
{-# INLINE isCmt #-}
isCdata = isCdata . getNode
{-# INLINE isCdata #-}
isPi = isPi . getNode
{-# INLINE isPi #-}
isElem = isElem . getNode
{-# INLINE isElem #-}
isRoot = isRoot . getNode
{-# INLINE isRoot #-}
isDTD = isDTD . getNode
{-# INLINE isDTD #-}
isAttr = isAttr . getNode
{-# INLINE isAttr #-}
isError = isError . getNode
{-# INLINE isError #-}
mkText = mkLeaf . mkText
{-# INLINE mkText #-}
mkBlob = mkLeaf . mkBlob
{-# INLINE mkBlob #-}
mkCharRef = mkLeaf . mkCharRef
{-# INLINE mkCharRef #-}
mkEntityRef = mkLeaf . mkEntityRef
{-# INLINE mkEntityRef #-}
mkCmt = mkLeaf . mkCmt
{-# INLINE mkCmt #-}
mkCdata = mkLeaf . mkCdata
{-# INLINE mkCdata #-}
mkPi n = mkLeaf . mkPi n
{-# INLINE mkPi #-}
mkError l = mkLeaf . mkError l
{-# INLINE mkError #-}
getText = getText . getNode
{-# INLINE getText #-}
getBlob = getBlob . getNode
{-# INLINE getBlob #-}
getCharRef = getCharRef . getNode
{-# INLINE getCharRef #-}
getEntityRef = getEntityRef . getNode
{-# INLINE getEntityRef #-}
getCmt = getCmt . getNode
{-# INLINE getCmt #-}
getCdata = getCdata . getNode
{-# INLINE getCdata #-}
getPiName = getPiName . getNode
{-# INLINE getPiName #-}
getPiContent = getPiContent . getNode
{-# INLINE getPiContent #-}
getElemName = getElemName . getNode
{-# INLINE getElemName #-}
getAttrl = getAttrl . getNode
{-# INLINE getAttrl #-}
getDTDPart = getDTDPart . getNode
{-# INLINE getDTDPart #-}
getDTDAttrl = getDTDAttrl . getNode
{-# INLINE getDTDAttrl #-}
getAttrName = getAttrName . getNode
{-# INLINE getAttrName #-}
getErrorLevel = getErrorLevel . getNode
{-# INLINE getErrorLevel #-}
getErrorMsg = getErrorMsg . getNode
{-# INLINE getErrorMsg #-}
changeText = changeNode . changeText
{-# INLINE changeText #-}
changeBlob = changeNode . changeBlob
{-# INLINE changeBlob #-}
changeCmt = changeNode . changeCmt
{-# INLINE changeCmt #-}
changeName = changeNode . changeName
{-# INLINE changeName #-}
changeElemName = changeNode . changeElemName
{-# INLINE changeElemName #-}
changeAttrl = changeNode . changeAttrl
{-# INLINE changeAttrl #-}
changeAttrName = changeNode . changeAttrName
{-# INLINE changeAttrName #-}
changePiName = changeNode . changePiName
{-# INLINE changePiName #-}
changeDTDAttrl = changeNode . changeDTDAttrl
{-# INLINE changeDTDAttrl #-}
mkElement :: QName -> XmlTrees -> XmlTrees -> XmlTree
mkElement n al = mkTree (mkElementNode n al)
{-# INLINE mkElement #-}
mkRoot :: XmlTrees -> XmlTrees -> XmlTree
mkRoot al = mkTree (mkElementNode (mkName t_root) al)
mkAttr :: QName -> XmlTrees -> XmlTree
mkAttr n = mkTree (mkAttrNode n)
{-# INLINE mkAttr #-}
mkDTDElem :: DTDElem -> Attributes -> XmlTrees -> XmlTree
mkDTDElem e al = mkTree (mkDTDNode e al)
addAttr :: XmlTree -> XmlTrees -> XmlTrees
addAttr a al
| isAttr a = add al
| otherwise = al
where
an = (qualifiedName . fromJust . getAttrName) a
add []
= [a]
add (a1:al1)
| isAttr a1
&&
(qualifiedName . fromJust . getAttrName) a1 == an
= a : al1
| otherwise
= a1 : add al1
mergeAttrl :: XmlTrees -> XmlTrees -> XmlTrees
mergeAttrl = foldr addAttr
mkElement' :: QName -> XmlTrees -> XmlTrees -> XmlTree
mkElement' n al cl = id $!! mkElement n al cl
{-# INLINE mkElement' #-}
mkRoot' :: XmlTrees -> XmlTrees -> XmlTree
mkRoot' al cl = id $!! mkRoot al cl
{-# INLINE mkRoot' #-}
mkAttr' :: QName -> XmlTrees -> XmlTree
mkAttr' n av = id $!! mkAttr n av
{-# INLINE mkAttr' #-}
mkText' :: String -> XmlTree
mkText' t = id $!! mkText t
{-# INLINE mkText' #-}
mkCharRef' :: Int -> XmlTree
mkCharRef' i = id $!! mkCharRef i
{-# INLINE mkCharRef' #-}
mkEntityRef' :: String -> XmlTree
mkEntityRef' n = id $!! mkEntityRef n
{-# INLINE mkEntityRef' #-}
mkCmt' :: String -> XmlTree
mkCmt' c = id $!! mkCmt c
{-# INLINE mkCmt' #-}
mkCdata' :: String -> XmlTree
mkCdata' d = id $!! mkCdata d
{-# INLINE mkCdata' #-}
mkPi' :: QName -> XmlTrees -> XmlTree
mkPi' n v = id $!! mkPi n v
{-# INLINE mkPi' #-}
mkError' :: Int -> String -> XmlTree
mkError' l m = id $!! mkError l m
{-# INLINE mkError' #-}
mkDTDElem' :: DTDElem -> Attributes -> XmlTrees -> XmlTree
mkDTDElem' e al cl = id $!! mkDTDElem e al cl
{-# INLINE mkDTDElem' #-}
toText :: XmlTree -> XmlTree
toText t
| isCharRef t
= mkText
. (:[]) . toEnum
. fromJust
. getCharRef
$ t
| isCdata t
= mkText
. fromJust
. getCdata
$ t
| otherwise
= t
concText :: XmlTree -> XmlTree -> XmlTrees
concText t1 t2
| isText t1 && isText t2
= (:[]) . mkText $ fromJust (getText t1) ++ fromJust (getText t2)
| otherwise
= [t1, t2]
mergeText :: XmlTree -> XmlTree -> XmlTrees
mergeText
= concText `on` toText