XML.hs revision 668c9c725a11c0f77057152148570af853a1bc0d
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian MaederModule : $Header$
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian MaederCopyright : (c) Felix Gabriel Mance
97018cf5fa25b494adffd7e9b4e87320dae6bf47Christian MaederLicense : GPLv2 or higher, see LICENSE.txt
b4fbc96e05117839ca409f5f20f97b3ac872d1edTill MossakowskiMaintainer : f.mance@jacobs-university.de
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian MaederStability : provisional
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian MaederPortability : portable
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian MaederOWL2 XML Syntax Parsing
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maederimport qualified Data.Map as Map
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maedertype XMLBase = String
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian Maeder-- ^ error messages for the parser
b645cf3dc1e449038ed291bbd11fcc6e02b2fc7fChristian Maedererr :: String -> t
ebcaad207cafc89eeb49d431f40de2ef4c48411cChristian Maedererr s = error $ "XML parser: " ++ s
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder{- two functions from Text.XML.Light.Proc version 1.3.7 for compatibility
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder with previous versions -}
b645cf3dc1e449038ed291bbd11fcc6e02b2fc7fChristian MaedervLookupAttrBy :: (Text.XML.Light.QName -> Bool) -> [Attr] -> Maybe String
715ffaf874309df081d1e1cd8e05073fc1227729Christian MaedervLookupAttrBy p as = attrVal `fmap` find (p . attrKey) as
715ffaf874309df081d1e1cd8e05073fc1227729Christian MaedervFindAttrBy :: (Text.XML.Light.QName -> Bool) -> Element -> Maybe String
715ffaf874309df081d1e1cd8e05073fc1227729Christian MaedervFindAttrBy p e = vLookupAttrBy p (elAttribs e)
715ffaf874309df081d1e1cd8e05073fc1227729Christian MaederisSmth :: String -> Text.XML.Light.QName -> Bool
715ffaf874309df081d1e1cd8e05073fc1227729Christian MaederisSmth s = (s ==) . qName
715ffaf874309df081d1e1cd8e05073fc1227729Christian MaederisSmthList :: [String] -> Text.XML.Light.QName -> Bool
715ffaf874309df081d1e1cd8e05073fc1227729Christian MaederisSmthList l qn = qName qn `elem` l
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian MaederisNotSmth :: Text.XML.Light.QName -> Bool
38775225cf810f5895cc03b4acbcfe8f84f2513aChristian MaederisNotSmth q = let qn = qName q in qn `notElem` ["Declaration",
ccf3de3d66b521a260e5c22d335c64a48e3f0195Christian Maeder "Prefix", "Import", "Annotation"]
ccf3de3d66b521a260e5c22d335c64a48e3f0195Christian MaederfilterCh :: String -> Element -> [Element]
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian MaederfilterCh s = filterChildrenName (isSmth s)
dfa74d066ea0f00a70276aedecc624c6b3c86deaChristian MaederfilterChL :: [String] -> Element -> [Element]
ccf3de3d66b521a260e5c22d335c64a48e3f0195Christian MaederfilterChL l = filterChildrenName (isSmthList l)
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian MaederfilterC :: String -> Element -> Element
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian MaederfilterC s e = fromMaybe (err "child not found")
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder (filterChildName (isSmth s) e)
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian MaederfilterCL :: [String] -> Element -> Element
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian MaederfilterCL l e = fromMaybe (err "child not found")
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder (filterChildName (isSmthList l) e)
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder-- ^ parses an IRI
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian MaedergetIRI :: XMLBase -> Element -> IRI
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder let [a] = elAttribs e
d17834302eaa101395b4b806cd73670fd864445fChristian Maeder iri = attrVal a
ccf3de3d66b521a260e5c22d335c64a48e3f0195Christian Maeder ty = case qName $ attrKey a of
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder "abbreviatedIRI" -> Abbreviated
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder "IRI" -> Full
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder "nodeID" -> NodeID
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder _ -> err "invalid type of iri"
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder in appendBase b $ nullQName {localPart = iri, iriType = ty}
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder{- | if the IRI contains colon, it is split there;
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maederelse, the xml:base needs to be prepended to the local part
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maederand then the IRI must be splitted -}
715ffaf874309df081d1e1cd8e05073fc1227729Christian MaederappendBase :: XMLBase -> IRI -> IRI
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian MaederappendBase b qn =
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder let r = localPart qn
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder in if ':' `elem` r then splitIRI qn
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder else splitIRI $ qn {localPart = b ++ r, iriType = Full}
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder-- ^ splits an IRI at the colon
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian MaedersplitIRI :: IRI -> IRI
836e72a3c413366ba9801726f3b249c7791cb9caChristian MaedersplitIRI qn = case iriType qn of
836e72a3c413366ba9801726f3b249c7791cb9caChristian Maeder NodeID -> nodeID qn
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder _ -> let lp = localPart qn
7dec34aee2b609b9535c48d060e0f7baf3536457Christian Maeder np = takeWhile (/= ':') lp
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder ':' : nlp = dropWhile (/= ':') lp
7dec34aee2b609b9535c48d060e0f7baf3536457Christian Maeder in qn {namePrefix = np, localPart = nlp}
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder-- ^ prepends "_:" to the nodeID if is not there already
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian MaedernodeID :: IRI -> IRI
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder let lp = localPart qn
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder in case lp of
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian Maeder '_' : ':' : t -> qn
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder _ -> qn {localPart = "_:" ++ lp}
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder-- ^ gets the content of an element with name IRI, AbbreviatedIRI or Import
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian MaedercontentIRI :: XMLBase -> Element -> IRI
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian MaedercontentIRI b e =
797f811e57952d59e73b8cd03b667eef276db972Christian Maeder let cont = strContent e
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder iri = nullQName {localPart = cont}
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder in case getName e of
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder "AbbreviatedIRI" -> splitIRI iri
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder "IRI" -> if ':' `elem` cont then
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder splitIRI $ iri {iriType = Full}
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder else appendBase b iri
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder "Import" -> appendBase b $ iri {iriType = cssIRI cont}
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder _ -> err "invalid type of iri"
ccf3de3d66b521a260e5c22d335c64a48e3f0195Christian Maeder-- ^ gets the name of an axiom in XML Syntax
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian MaedergetName :: Element -> String
e1839fb37a3a2ccd457464cb0dcc5efd466dbe22Christian Maeder let n = (qName . elName) e
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder q = (qURI . elName) e
7dec34aee2b609b9535c48d060e0f7baf3536457Christian Maeder-- ^ gets the cardinality
7dec34aee2b609b9535c48d060e0f7baf3536457Christian MaedergetInt :: Element -> Int
1738d16957389457347bee85075d3d33d002158fChristian MaedergetInt e = let [int] = elAttribs e in value 10 $ attrVal int
1738d16957389457347bee85075d3d33d002158fChristian MaedergetEntityType :: String -> EntityType
33a5d53a412ba0a4e5847f7538d6da2e22bd116cChristian MaedergetEntityType ty = case ty of
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder "Class" -> Class
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder "Datatype" -> Datatype
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder "NamedIndividual" -> NamedIndividual
0f67ca7b0c738a28f6688ba6e96d44d7c14af611Christian Maeder "ObjectProperty" -> ObjectProperty
c70d42540b8f8c3c141cc0779599d25f7eb69bbfChristian Maeder "DataProperty" -> DataProperty
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder "AnnotationProperty" -> AnnotationProperty
b645cf3dc1e449038ed291bbd11fcc6e02b2fc7fChristian Maeder _ -> err "not entity type"
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian MaedertoEntity :: XMLBase -> Element -> Entity
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian MaedertoEntity b e = Entity (getEntityType $ (qName . elName) e) $ getIRI b e
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian MaedergetDeclaration :: XMLBase -> Element -> Axiom
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian MaedergetDeclaration b e = case getName e of
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder "Declaration" ->
88ece6e49930670e8fd3ee79c89a2e918d2fbd0cChristian Maeder let ent = filterCL entityList e
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder ans = getAllAnnos b e
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder entity@(Entity ty iri) = toEntity b ent
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder in case ty of
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder AnnotationProperty -> PlainAxiom (Misc ans) $ AnnFrameBit
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder [Annotation [] iri $ AnnValue iri] AnnotationFrameBit
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder _ -> PlainAxiom (SimpleEntity entity)
88ece6e49930670e8fd3ee79c89a2e918d2fbd0cChristian Maeder $ AnnFrameBit ans AnnotationFrameBit
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder _ -> err "not declaration"
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian MaederisPlainLiteral :: String -> Bool
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian MaederisPlainLiteral s =
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder "http://www.w3.org/1999/02/22-rdf-syntax-ns#PlainLiteral" == s
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian MaedergetLiteral :: XMLBase -> Element -> Literal
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian MaedergetLiteral b e = case getName e of
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder let lf = strContent e
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder mdt = findAttr (unqual "datatypeIRI") e
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder mattr = vFindAttrBy (isSmth "lang") e
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder in case mdt of
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder Nothing -> case mattr of
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder Just lang -> Literal lf (Untyped $ Just lang)
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder Nothing -> Literal lf (Untyped Nothing)
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder Just dt -> case mattr of
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder Just lang -> Literal lf (Untyped $ Just lang)
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder Nothing -> if isPlainLiteral dt then
88ece6e49930670e8fd3ee79c89a2e918d2fbd0cChristian Maeder Literal lf (Untyped Nothing)
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder else Literal lf (Typed $ appendBase b $
prefixDeclaration = Map.fromList $ getPrefixMap e