Extracting Class content such as (onProperty, somevalueFrom , unioinOf (which contain a collection) and equivalentClass)

StackOverflow https://stackoverflow.com/questions/19588885

문제

I'm trying to extract class's content from owl file which consists of onProperty and someValuesFrom where the someValueFrom consists of class that contain a unionOf (onProperty, someValueFrom and equivalentClass), I have created a SPARQL query to extract these data, however every time it returns blank nodes such as ":b0" and ":b1". Does anyone have any idea what should I do with my query in order to make it provide the needed results. This is my owl file:

<?xml version="1.0"?>
<rdf:RDF
    xmlns="http://owl.cs.manchester.ac.uk/2009/07/sssw/people#"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
    xmlns:owl="http://www.w3.org/2002/07/owl#"
    xmlns:ns0="http://owl.cs.manchester.ac.uk/2009/07/sssw/people#"
    xml:base="http://owl.cs.manchester.ac.uk/2009/07/sssw/people">
  <owl:Ontology rdf:about="http://owl.cs.manchester.ac.uk/2009/07/sssw/people"/>
  <owl:Class rdf:about="http://www.w3.org/2002/07/owl#Thing"/>
  <owl:Class rdf:about="http://owl.cs.manchester.ac.uk/2009/07/sssw/people#haulage_worker">
    <rdfs:comment rdf:datatype="http://www.w3.org/2001/XMLSchema#string"
    ></rdfs:comment>
    <owl:equivalentClass>
      <owl:Restriction>
         <owl:onProperty>
          <owl:ObjectProperty rdf:about="http://owl.cs.manchester.ac.uk/2009/07/sssw/people#works_for"/>
        </owl:onProperty>
        <owl:someValuesFrom>
          <owl:Class>
            <owl:unionOf rdf:parseType="Collection">
              <owl:Restriction>
                <owl:onProperty>
                  <owl:ObjectProperty rdf:about="http://owl.cs.manchester.ac.uk/2009/07/sssw/people#part_of"/>
                </owl:onProperty>
                <owl:someValuesFrom>
                  <owl:Class rdf:about="http://owl.cs.manchester.ac.uk/2009/07/sssw/people#haulage_company"/>
                </owl:someValuesFrom>
               </owl:Restriction>
              <owl:Class rdf:about="http://owl.cs.manchester.ac.uk/2009/07/sssw/people#haulage_company"/>
            </owl:unionOf>
          </owl:Class>
         </owl:someValuesFrom>
      </owl:Restriction>
    </owl:equivalentClass>
    <rdfs:label rdf:datatype="http://www.w3.org/2001/XMLSchema#string"
    >haulage worker</rdfs:label>
  </owl:Class>
 </rdf:RDF>

and This is my SPARQL query that I have created :

    prefix abc: <http://owl.cs.manchester.ac.uk/2009/07/sssw/people#>
    prefix ghi: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
    prefix mno: <http://www.w3.org/2001/XMLSchema#>
    prefix owl: <http://www.w3.org/2002/07/owl#>
    prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
    prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
    prefix list: <http://jena.hpl.hp.com/ARQ/list#>

    select distinct ?class ?ObjectProperty ?someValuesFrom ?otherClass where { ?class a  owl:Class .


    OPTIONAL{
       ?class owl:equivalentClass ?e .
        ?e a owl:Restriction .
#       ?e owl:onProperty ?ObjectProperty .
        ?e owl:someValuesFrom [ a owl:Class; 
                                    owl:unionOf [ rdf:first ?    ObjectProperty; 
                                    rdf:rest ?someValuesFrom ;     rdf:rest*/rdf:first ?otherClass]] .  


      }
     FILTER( STRSTARTS(STR(?class),STR(owl:)) || STRSTARTS(STR(?class),STR(abc:)))  
    }group by ?class  ?ObjectProperty ?someValuesFrom ?otherClass
    order by ?class

and This is the result that I had got :

-------------------------------------------------------------------------------
| class               | ObjectProperty | someValuesFrom | otherClass          |
===============================================================================
| abc:haulage_company |                |                |                     |
| abc:haulage_worker  | _:b0           | _:b1           | _:b0                |
| abc:haulage_worker  | _:b0           | _:b1           | abc:haulage_company |
| owl:Thing           |                |                |                     |
-------------------------------------------------------------------------------

but the expected result is :

-----------------------------------------------------------------------------
| class               | ObjectProperty | someValuesFrom   | otherClass      |
=============================================================================
| abc:haulage_company |                |                  |                 |
| abc:haulage_worker  | abc:works_for  |                  |                 |
| abc:haulage_worker  | abc:part_of    | haulage_company  | haulage_company |
| owl:Thing           |                |                  |                 |
-----------------------------------------------------------------------------

What should I do with my SPARQL query in order to make return this result?

Many thanks in advance :)

도움이 되었습니까?

해결책

The problem with your query:

It may be easier to understand the results of the SPARQL query if you look at your data in the Turtle serialization rather than the RDF/XML serialization. The relevant portion of your data is:

ns0:haulage_worker  a        owl:Class ;
        rdfs:comment         ""^^xsd:string ;
        rdfs:label           "haulage worker"^^xsd:string ;
        owl:equivalentClass  [ a                   owl:Restriction ;
                               owl:onProperty      ns0:works_for ;
                               owl:someValuesFrom  [ a            owl:Class ;
                                                     owl:unionOf  ( [ a                   owl:Restriction ;
                                                                      owl:onProperty      ns0:part_of ;
                                                                      owl:someValuesFrom  ns0:haulage_company
                                                                    ] ns0:haulage_company )
                                                   ]

Consider the match for the part about owl:unionOf. In your query, it's

owl:unionOf  ( [ a                   owl:Restriction ;
                 owl:onProperty      ns0:part_of ;
                 owl:someValuesFrom  ns0:haulage_company ]
               ns0:haulage_company )

The elements of the list are a blank node with some properties, and ns0:haulage_company. The query that should match some of this data is:

owl:unionOf [ rdf:first ?ObjectProperty; 
              rdf:rest ?someValuesFrom ;
              rdf:rest*/rdf:first ?otherClass ]] .  

The thing that will match ?ObjectProperty is the first element of the list which, in this case, is not an object property, but is a blank node. The thing that will match ?someValuesFrom is the list node representing the rest of the list.

Fixing your query:

I'm not quite sure exactly what you are trying to return from this query. Based on your expected results, it looks like you're saying that a class ?class can be related to an owl:someValuesFrom restriction, in which case you want to bind ?ObjectProperty and ?someValuesFrom to the object property and class (if it's not a blank node), and bind ?otherClass to other related (non-blank) classes otherwise. You said you expected these results:

-----------------------------------------------------------------------------
| class               | ObjectProperty | someValuesFrom   | otherClass      |
=============================================================================
| abc:haulage_company |                |                  |                 |
| abc:haulage_worker  | abc:works_for  |                  |                 |
| abc:haulage_worker  | abc:part_of    | haulage_company  | haulage_company |
| owl:Thing           |                |                  |                 |
-----------------------------------------------------------------------------

but if my understanding is correct, I think it would be easier and more useful to get something like:

-----------------------------------------------------------------------------
| class               | ObjectProperty | someValuesFrom   | otherClass      |
=============================================================================
| abc:haulage_company |                |                  |                 |
| abc:haulage_worker  | abc:works_for  |                  |                 |
| abc:haulage_worker  | abc:part_of    | haulage_company  |                 |
| abc:haulage_worker  |                |                  | haulage_company |
| owl:Thing           |                |                  |                 |
-----------------------------------------------------------------------------

You can do that with a query like this:

prefix :      <http://owl.cs.manchester.ac.uk/2009/07/sssw/people#>
prefix owl:   <http://www.w3.org/2002/07/owl#>
prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

select distinct ?class ?onProperty ?someValuesFrom ?otherClass where {
  #-- Select each named class.
  ?class a owl:Class .
  filter( !isBlank( ?class ))

  optional {
    #-- Find "related" classes by following a somewhat complex
    #-- property path that will follow equivalent classes,
    #-- existential restrictions, and unionOf expressions.
    ?class (owl:equivalentClass
           |owl:someValuesFrom
           |(owl:unionOf/rdf:rest*/rdf:first))+ ?r .

    #-- Save non-blank related classes as ?otherClass.
    bind(if(isBlank(?r),?unbound,?r) as ?otherClass)

    #-- If the related class is a restriction, then we can 
    #-- take its owl:onProperty and owl:someValuesFrom.
    optional { 
      ?r owl:onProperty ?onProperty ;
         owl:someValuesFrom ?svf .
      bind( if(isBlank(?svf),?unbound,?svf) as ?someValuesFrom )
    }
  }
}
values ?unbound { UNDEF }

The pattern to save values that aren't bound to blank nodes is described in answers to an answers.semanticweb.com question, Binding a variable only when another is non-blank? The idea is to use values ?unbound { UNDEF } to ensure that ?unbound always has an undefined value, and then to use bind and if to assign either ?unbound or some other value to a projected variable. In essence, it's this:

bind(if(isBlank(...),?unbound,...) as ...)
values ?unbound { UNDEF }

The results are

-----------------------------------------------------------------------
| class            | onProperty | someValuesFrom   | otherClass       |
=======================================================================
| owl:Thing        |            |                  |                  |
| :haulage_company |            |                  |                  |
| :haulage_worker  |            |                  |                  |
| :haulage_worker  | :works_for |                  |                  |
| :haulage_worker  | :part_of   | :haulage_company |                  |
| :haulage_worker  |            |                  | :haulage_company |
-----------------------------------------------------------------------

This does include a row for :haulage_worker that doesn't have bindings for any of the other variables, but I think that's OK, since you already wanted such rows for owl:Thing and :haulage_company.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top