Warning:
This wiki has been archived and is now read-only.
ORG Validation Suite
This page describes a verification suite to assist implementers of ORG in checking that they are using the vocabulary appropriately. It is provided to support gathering implementation evidence as part of the W3C REC track process.
Contents
Verification approach
ORG provides a collection of terms intended to be useful for describing various aspects of organizations and organizational structure. Validating usage of such a vocabulary is difficult and cannot be completely automated.
- There are few formal semantic constraints on the use vocabulary terms. The intended usage of terms is largely carried in the prose descriptions of them.
- Implementers are free to use a subset of terms and to use additional terms (for cases where the coverage of ORG is insufficient).
- There are no constraints on what it means to consume ORG data. The information may simply be published in machine readable form (e.g. as part of a government transparency initiative), may be used to drive visualizations of organizational structure or may be used in a more operational setting.
Our approach is to provide the specification for a minimal ORG consumer that extracts and describes different ORG resources from a data source. For example, given an organization then one affordance is to locate all sub organzations or organizational units. An implementation checker (a human) can thus walk through a sample ORG data source using the minimal consumer and confirm that the resources found match those expected from the source data. Verifying that the returned results are correct requires human interpretation.
We formalize this minimal ORG consumer as a set of SPARQL queries. To simplify testing the Working Group intends to offer an on line service which provides a simple HTML rendering of an ORG data source based on these queries.
A preliminary version of this service is available at: http://gld01.w3.org/
The display generated by this service on the test sample data below is visible at: http://gld01.w3.org/view?upload=upload-2013-05-22T15-39-45-0
Query set
Many of the verification queries are intended to extract part of the description of an organization. In the queries specified here the string $org
should be replaced by <uri>
where uri is the URI of the org:Organization instance being examined.
All SPARQL queries and update specifications below assume the following prefix declarations:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX dct: <http://purl.org/dc/terms/>
PREFIX vcard: <http://www.w3.org/2006/vcard/ns#>
PREFIX org: <http://www.w3.org/ns/org#>
Inference closure
Before applying any verification queries an inference closure should be formed as follows:
- Create an RDF graph comprising the union of:
- the data sample to be checked
- the ORG ontology
- any additional ontologies used in the implementation which declare mapping relationships between ORG and implementation-specific terms
- Form an inference closure by applying the following SPARQL UPDATE on the graph:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX org: <http://www.w3.org/ns/org#>
INSERT {
?x ?p ?y .
} WHERE {
?sp rdfs:subPropertyOf+ ?p .
?x ?sp ?y .
};
INSERT {
?i a ?c .
} WHERE {
?p rdfs:domain ?c .
?i ?p ?x .
};
INSERT {
?i a ?c .
} WHERE {
?p rdfs:range ?c .
?x ?p ?i .
};
INSERT {
?i a ?c .
} WHERE {
?sc rdfs:subClassOf+ ?c .
?i a ?sc .
};
INSERT {
?x ?p ?y .
} WHERE {
?ip owl:inverseOf ?p .
?y ?ip ?x.
};
INSERT {
?agent ?roleprop ?org.
} WHERE {
[] a org:Membership;
org:member ?agent;
org:organization ?org;
org:role [ org:roleProperty ?roleprop ].
};
INSERT {
?agent org:memberOf ?org.
} WHERE {
?agent org:holds ?post.
?post org:postIn ?org.
};
INSERT {
[] a org:Membership;
org:member ?agent;
org:organization ?org;
org:role ?role.
} WHERE {
?agent org:holds ?post.
?post org:postIn ?org.
?post org:role ?role.
};
INSERT {
?agent org:memberOf ?org.
} WHERE {
[] a org:Membership;
org:member ?agent;
org:organization ?org.
}
Any alternative inference closure process which computes (a super set of) those found by this SPARQL UPDATE may be used.
Core
List all organizations mentioned in the data.
SELECT * WHERE {
?org a org:Organization .
OPTIONAL {?org skos:prefLabel ?prefLabel}
OPTIONAL {?org rdfs:label ?label}
OPTIONAL {?org dct:description ?description}
OPTIONAL {?org org:identifier ?identifier}
OPTIONAL {?org org:classification ?classification}
}
Structure
List all sub-organizations of a given organization.
SELECT * WHERE {
?subOrganization org:subOrganizationOf $org .
OPTIONAL {
?subOrganization org:unitOf $org .
BIND (true AS ?isUnitOf)
}
}
Sites
List all sites of a given organization.
Note that the site information itself is OPTIONAL since the specification imposes no constraints on address representation and the recommended vocabulary (vcard) is currently subject to revision.
SELECT * WHERE {
$org org:hasSite ?site .
OPTIONAL {
$org org:hasPrimarySite ?site .
BIND (true AS ?isPrimarySite)
}
OPTIONAL {
$org org:hasRegisteredSite ?site .
BIND (true AS ?isRegisteredSite)
}
OPTIONAL {
?site org:siteAddress ?address .
OPTIONAL { ?address vcard:fn ?sitename }
OPTIONAL { ?address vcard:tel / rdf:value ?telephone }
OPTIONAL { ?address vcard:adr / vcard:street-address ?street }
OPTIONAL { ?address vcard:adr / vcard:locality ?locality }
}
}
Membership
List members of an organization.
SELECT * WHERE {
?member org:memberOf $org .
OPTIONAL {
?member org:headOf $org .
BIND (true as ?isHeadOf)
}
OPTIONAL { [] org:member ?member ; org:organization $org; org:role ?role }
OPTIONAL { ?member org:reportsTo ?reportsTo }
OPTIONAL { ?member org:location ?location }
}
Posts
List posts in an organization, some post information is also tested by the membership query thanks to the closure rules.
SELECT * WHERE {
?post org:postIn $org .
OPTIONAL { ?post org:reportsTo ?reportsTo }
OPTIONAL { ?post org:heldBy ?postHolder }
OPTIONAL { ?post org:role ?postRole }
}
Organization change
Lists event(s) which resulted in this organization and the associated precursor organizations.
SELECT * WHERE {
$org org:resultedFrom ?event .
OPTIONAL { ?event org:originalOrganization ?originalOrganization }
}
Collaboration
Lists consortia, projects or other collaborations which this organization is engaged in.
SELECT ?collaboration ?partner WHERE {
$org org:memberOf ?collaboration .
?collaboration a org:OrganizationalCollaboration;
OPTIONAL {
?partner org:memberOf ?collaboration .
FILTER (?partner != $org)
}
}
Example
This example demonstrates the result of the above verification queries when run on the following test data. Note that this sample is design to be an abstract, minimal test of the different features of ORG and not representative of real world organizations.
Example test data
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix dct: <http://purl.org/dc/terms/> .
@prefix vcard: <http://www.w3.org/2006/vcard/ns#> .
@prefix prov: <http://www.w3.org/ns/prov#> .
@prefix vcard: <http://www.w3.org/2006/vcard/ns#> .
@prefix org: <http://www.w3.org/ns/org#> .
@prefix : <http://example.com/sample1#> .
# Organizations
:org1 a org:FormalOrganization;
skos:prefLabel "Org 1";
org:hasUnit :unit1, :unit2 ;
.
:unit1 a org:OrganizationalUnit;
skos:prefLabel "Unit 1";
org:hasRegisteredSite :site1;
.
:unit2 a org:OrganizationalUnit;
skos:prefLabel "Unit 2";
.
# Sites
:site1 a org:Site ;
rdfs:label "Site 1";
org:siteAddress [
a vcard:VCard;
vcard:fn "Registered site for unit 1";
vcard:tel [ rdf:value "1234" ];
vcard:adr [ vcard:street-address "1 The Street"; vcard:locality "Our town"; vcard:postal-code "A1 42Z" ];
]
.
# Posts
:assistantPost a org:Post;
rdfs:label "Post of assistant to unit1's manager";
org:postIn :unit1;
org:role :assistant;
org:reportsTo :managerPost;
.
:managerPost a org:Post;
rdfs:label "Post of manager of unit1";
org:postIn :unit1;
org:role :manager;
.
# Roles
:manager a org:Role;
rdfs:label "Manager";
.
:assistant a org:Role;
rdfs:label "Assistant";
.
[] a org:Membership;
org:member :p1;
org:organization :unit1;
org:role :manager;
.
# People
:boss1 a foaf:Person;
foaf:name "The Boss";
org:headOf :org1;
.
:p2 a foaf:Person;
foaf:name "Person 2";
org:reportsTo :p1 ;
org:holds :assistantPost;
.
:p1 a foaf:Person;
foaf:name "Person 1";
org:reportsTo :boss1 ;
org:location "Mailstop 1/b";
.
# Organizational history
:unit1a a org:OrganizationalUnit;
skos:prefLabel "Unit 1a";
.
:unit1b a org:OrganizationalUnit;
skos:prefLabel "Unit 1b";
.
:merger1 a org:ChangeEvent;
rdfs:label "Unit merger";
org:originalOrganization :unit1a, :unit1b;
org:resultingOrganization :unit1 ;
.
# Collaborations
:initiative a org:OrganizationalCollaboration;
rdfs:label "Our cross-organizational initiative";
org:hasMember :unit1, :unit2;
.
Example result
*** List all organizations mentioned in the data
org = http://example.com/sample1#unit2 (Unit 2)
prefLabel = Unit 2
org = http://example.com/sample1#org1 (Org 1)
prefLabel = Org 1
org = http://example.com/sample1#initiative (Our cross-organizational initiative)
label = Our cross-organizational initiative
org = http://example.com/sample1#unit1a (Unit 1a)
prefLabel = Unit 1a
org = http://example.com/sample1#unit1b (Unit 1b)
prefLabel = Unit 1b
org = http://example.com/sample1#unit1 (Unit 1)
prefLabel = Unit 1
*** List all sub-organizations of a given organization
Result for :org1
subOrganization = http://example.com/sample1#unit1 (Unit 1)
isUnitOf = true
subOrganization = http://example.com/sample1#unit2 (Unit 2)
isUnitOf = true
*** List all sites of a given organization
Result for :unit1
site = http://example.com/sample1#site1 (Site 1)
isPrimarySite = true
isRegisteredSite = true
address = []
sitename = Registered site for unit 1
telephone = 1234
street = 1 The Street
locality = Our town
*** List members of an organization
Result for :unit1
member = http://example.com/sample1#p2 (Person 2)
role = http://example.com/sample1#assistant (Assistant)
reportsTo = http://example.com/sample1#p1 (Person 1)
member = http://example.com/sample1#p1 (Person 1)
role = http://example.com/sample1#manager (Manager)
reportsTo = http://example.com/sample1#boss1 (The Boss)
location = Mailstop 1/b
Result for :initiative
member = http://example.com/sample1#unit2 (Unit 2)
member = http://example.com/sample1#unit1 (Unit 1)
Result for :org1
member = http://example.com/sample1#boss1 (The Boss)
isHeadOf = true
*** List posts in an organization, some post information is also tested by the members query thanks to the closure rules.
Result for :unit1
post = http://example.com/sample1#managerPost (Post of manager of unit1)
postRole = http://example.com/sample1#manager (Manager)
post = http://example.com/sample1#assistantPost (Post of assistant to unit1's manager)
reportsTo = http://example.com/sample1#managerPost (Post of manager of unit1)
postHolder = http://example.com/sample1#p2 (Person 2)
postRole = http://example.com/sample1#assistant (Assistant)
*** Lists event(s) which resulted in this organization and the associated precursor organizations
Result for :unit1
event = http://example.com/sample1#merger1 (Unit merger)
originalOrganization = http://example.com/sample1#unit1a (Unit 1a)
event = http://example.com/sample1#merger1 (Unit merger)
originalOrganization = http://example.com/sample1#unit1b (Unit 1b)
*** Lists consortia, projects or other collaborations which this organization is engaged in
Result for :unit2
collaboration = http://example.com/sample1#initiative (Our cross-organizational initiative)
partner = http://example.com/sample1#unit1 (Unit 1)
Result for :unit1
collaboration = http://example.com/sample1#initiative (Our cross-organizational initiative)
partner = http://example.com/sample1#unit2 (Unit 2)