packages feed

hxt-7.1: doc/cookbook/RDFParser.hs

{- |
   Module     : RDFParser 
   Author     : Manuel Ohlendorf  

   Maintainer : Manuel Ohlendorf
   Stability  : experimental
   Portability: portable
   Version    :

Arrows to parse an RDF\/XML document. Two versions of processing arrows are provided. 

parseRDF normalises the document before it parses the document and creates the list of triples. 

processRDF expects a normalised document for parsing.
-}

module RDFParser (processRDF,parseRDF) 
where

import Text.XML.HXT.Arrow
import RDFDataTypes
import RDFFunctions
import RDFNormalize

-- -------------------------------------------------------------
-- ***** PARSEN ****
-- -------------------------------------------------------------

-- | normalises the document and then parses it.
--
-- > normalizeRDF >>> processRDF
--
-- see 'normalizeRDF'
parseRDF :: IOSArrow XmlTree RDFStore
parseRDF = normalizeRDF >>> processRDF

-- | just processes the document and does not do any normalisation.
processRDF :: (ArrowXml a) => a XmlTree RDFStore
processRDF = getChildren >>> isRDF `guards` arr triples  

-- | stores the resulting triples in a list
triples :: XmlTree -> RDFStore 
triples = runLA  ( processSubject)

-- | processes the node elements
processSubject :: (ArrowXml a) => a XmlTree Triple 
processSubject 
    = getChildren >>> (isNodeElem `guards` (arr getTriple $< blankOrNot))
    where
    blankOrNot 
        = ifA hasNodeID
        ((getQAttrValue rdf_nodeID >>> arr mkSubjectBlankNode) &&& getAttrValue "xml:lang") 
        ((getQAttrValue rdf_about >>> arr mkURIRef) &&& getAttrValue "xml:lang")

-- | processes the property nodes
processPredicate :: (ArrowXml a) => a XmlTree Predicate  
processPredicate 
    = choiceA [ hasResourceParseType :-> (getUniversalUri >>> arr mkPredicate),
               this :-> (getUniversalUri >>> arr mkPredicate)
              ]
-- | generates the object elements
processObject :: (ArrowXml a) => String -> a XmlTree Object 
processObject lang
    = choiceA [isResource                    :-> (getQAttrValue rdf_resource >>> arr mkResource)  
              ,(isEmptyElem >>> hasNodeID)   :-> (getQAttrValue rdf_nodeID >>> arr mkObjectBlankNode)
              ,hasDatatype                   :-> op1
              ,hasLiteralParseType           :-> op2
              ,hasAttr "xml:lang"            :-> ((getAttrValue "xml:lang"  &&& xshow getChildren) >>> arr2 mkLangLiteral)
              ,isA(const (length lang /= 0)) :-> (xshow getChildren >>> arr (mkLangLiteral lang))
              ,this                          :-> (xshow getChildren >>> arr mkLiteral)  
              ]
                where
                op1 = getQAttrValue rdf_datatype &&& (xshow getChildren) >>> arr2 mkTypedLiteral
                op2 = xshow getChildren >>> arr (mkTypedLiteral xmlliteral)

-- generates the whole triple
getTriple :: (ArrowXml a) => (Subject, String) -> a XmlTree Triple 
getTriple (subject,lang)
        = getChildren >>> (processPredicate &&& processObject lang) >>> arr2 (mkTriple subject)