Search code examples
xmlhaskellhxt

How to get first element of getChildren HXT?


So i'm having an issue with HXT, and i do not know how do i get the first element on that :

<rdfs:subClassOf rdf:resource="http://www.xfront.com/owl/ontologies/camera/#PurchaseableItem"/>
<owl:disjointWith rdf:Description="Hello"/>
<owl:disjointWith rdf:Description="Hello1"/>
<owl:disjointWith rdf:Description="Hello2"/>
<owl:disjointWith rdf:Description="Hello3"/>
<owl:disjointWith rdf:Description="Hello4"/>

<owl:equivalentClass> 
    <owl:Class>
        <owl:intersectionOf rdf:parseType="Collection">
        <rdf:Description rdf:about="http://www.xfront.com/owl/ontologies/camera/#Body"/>
        <owl:Restriction>
            <owl:onProperty rdf:resource="http://www.xfront.com/owl/ontologies/camera/#shutter-speed"/>
            <owl:cardinality rdf:datatype="http://www.w3.org/2001/XMLSchema#nonNegativeInteger">0</owl:cardinality>
        </owl:Restriction>
        </owl:intersectionOf>
    </owl:Class>
</owl:equivalentClass>

I do a getChildren which gives me that answer (two get Children) but i don't want have all these information ! I just want the first line of these getChildren ! Which is : <rdfs:subClassOf.../>and <owl:equivalentClass>

How could i do that ? Thankfully,

P.S.:

By the way,getChildren return a list of children right ? I did the trick to get the first element of getChildren which is : getChildren >. (!! 0) and it doesn't work ! Giving me some errors about index too large...


Solution

  • Repeated similar question with explanation answer here.

    import "hxt" Control.Arrow.ArrowTree (changeChildren, getChildren) 
    
    getNthChild :: (ArrowTree a, Tree t) => Int -> a (t b) (t b)
    getNthChild n = changeChildren (take 1 . drop n) >>> getChildren
    

    Update: easier alternative with hxt-xpath

    fname = "http://protege.cim3.net/file/pub/ontologies/camera/camera.owl" 
    
    myArrow = readDocument [withValidate no,
                            withCheckNamespaces yes,
                            withSubstDTDEntities no, withHTTP []] fname 
              >>> getXPathTrees "/rdf:RDF/owl:Class[1]" 
              >>> getAttrValue "rdf:ID"
    
    main = do
             results <- runX myArrow
             print results 
    

    result:

    ["Money"]
    

    Update: working getNthChild, filtering non-element children

    import qualified Text.XML.HXT.DOM.XmlNode as XN
    
    getNthChild :: (ArrowTree a, Tree t, XN.XmlNode b) => Int -> a (t b) (t b)
    getNthChild n = changeChildren (take 1 . drop n . filter XN.isElem) 
                    >>> getChildren
    

    then

    myArrow = readDocument [withValidate no,
                            withCheckNamespaces yes,
                            withSubstDTDEntities no, withHTTP []] fname 
              >>> getXPathTrees "/rdf:RDF" 
              >>> getNthChild 1               -- second child
              >>> getAttrValue "rdf:ID"
    

    gives the same result as above.