module Data.GI.GIR.XMLUtils
( nodeToElement
, subelements
, localName
, lookupAttr
, GIRXMLNamespace(..)
, lookupAttrWithNamespace
, childElemsWithLocalName
, childElemsWithNSName
, firstChildWithLocalName
, getElementContent
, xmlLocalName
, xmlNSName
) where
import Text.XML (Element(elementNodes, elementName, elementAttributes),
Node(NodeContent, NodeElement), nameLocalName, Name(..))
import Data.Maybe (mapMaybe, listToMaybe)
import qualified Data.Map as M
import Data.Text (Text)
nodeToElement :: Node -> Maybe Element
nodeToElement (NodeElement e) = Just e
nodeToElement _ = Nothing
subelements :: Element -> [Element]
subelements = mapMaybe nodeToElement . elementNodes
localName :: Element -> Text
localName = nameLocalName . elementName
childElemsWithLocalName :: Text -> Element -> [Element]
childElemsWithLocalName n =
filter localNameMatch . subelements
where localNameMatch = (== n) . localName
childElemsWithNSName :: GIRXMLNamespace -> Text -> Element -> [Element]
childElemsWithNSName ns n = filter nameMatch . subelements
where nameMatch = (== name) . elementName
name = Name {
nameLocalName = n
, nameNamespace = Just (girNamespace ns)
, namePrefix = Nothing
}
firstChildWithLocalName :: Text -> Element -> Maybe Element
firstChildWithLocalName n = listToMaybe . childElemsWithLocalName n
getElementContent :: Element -> Maybe Text
getElementContent = listToMaybe . mapMaybe getContent . elementNodes
where getContent :: Node -> Maybe Text
getContent (NodeContent t) = Just t
getContent _ = Nothing
lookupAttr :: Name -> Element -> Maybe Text
lookupAttr attr element = M.lookup attr (elementAttributes element)
data GIRXMLNamespace = GLibGIRNS | CGIRNS | CoreGIRNS
deriving Show
girNamespace :: GIRXMLNamespace -> Text
girNamespace GLibGIRNS = "http://www.gtk.org/introspection/glib/1.0"
girNamespace CGIRNS = "http://www.gtk.org/introspection/c/1.0"
girNamespace CoreGIRNS = "http://www.gtk.org/introspection/core/1.0"
lookupAttrWithNamespace :: GIRXMLNamespace -> Name -> Element -> Maybe Text
lookupAttrWithNamespace ns attr element =
let attr' = attr {nameNamespace = Just (girNamespace ns)}
in M.lookup attr' (elementAttributes element)
xmlLocalName :: Text -> Name
xmlLocalName n = Name { nameLocalName = n
, nameNamespace = Nothing
, namePrefix = Nothing }
xmlNSName :: GIRXMLNamespace -> Text -> Name
xmlNSName ns n = Name { nameLocalName = n
, nameNamespace = Just (girNamespace ns)
, namePrefix = Nothing }