E-Business + Web Science Research Group

GoodRelations: An Ontology for Describing Web Offers

Important Note: This document is outdated and just kept for historic reasons.
The current version of the GoodRelations documentation is at

Primer and User's Guide

Draft 2008-11-27

This version: http://www.heppnetz.de/projects/goodrelations/primer/20081127/

Previous version: http://www.heppnetz.de/projects/goodrelations/primer/20080808/

Latest version: http://www.heppnetz.de/projects/goodrelations/primer/

Author: Martin Hepp, mhepp@computer.org (c) 2008 by Martin Hepp, http://www.heppnetz.de.

This documentation is available under a Creative Commons Attribution-No Derivative Works 3.0 Germany License. You are free to use and distribute this document as long as it remains unchanged. Note that this license applies only to the documentation. The GoodRelations ontology itself is available under a Creative Commons Attribution 3.0 license, which allows derived works etc.


A promising application domain for Semantic Web technology is the annotation of products and services offers on the Web so that consumers and enterprises can search for suitable suppliers more easily and more precisely, and so that retailers can easily reuse product model data from manufacturers. GoodRelations is a lightweight, generic vocabulary for the Semantic Web that allows expressing all typical aspects of offers for goods and services on the Web. For example, we often want to be able to express that a particular Web site describes an offer to sell cell phones of a certain make and model at a certain price, that a piano house offers maintenance for pianos that weigh less than 150 kg, or that a car rental company leases out cars of a certain make and model from a particular set of branches across the country.

The GoodRelations ontology provides a generic yet lightweight vocabulary for describing in a machine-readable way the details of offers made on the Semantic Web. This allows vendors to add a machine-readable definition of their offers so that Semantic Web search engines can find such Web resources more precisely. It empowers them to return exactly matching offers for a given need.

Such is in the interest of shop owners and manufacturers, because it makes sure the particular features and strengths of their products or services are considered by Semantic Web search engines, and it is in the interest of buyers, because it allows them to find offers that exactly fit their requirements. In addition, GoodRelations makes it easy to exchange product model details and feature data between manufacturers and shop operators, so that such data can be reused more easily along the value chain.


This primer is a draft, reflecting the current version v1 of the GoodRelations ontology available at http://purl.org/goodrelations/v1.


The ontology and documentation are provided as they are, without warranty of any kind, expressed or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the ontology or its documentation or the use or other dealings in the ontology or documentation.




In this section, we explain why GoodRelations is practically relevant and what it actually contributes.

1.1 Need for a Common Vocabulary for Web Offers

Imagine, you are searching for a particular type of product or service on the Web. Using standard search engines like Google or others can be a frustrating experience. This is for a number of reasons. First, when searching, you have to know and use the very same words and the same language as the vendor uses for describing the offer. If you search for "TV", you won’t find pages that use "television", for instance. Second, you have no means for narrowing down your search to offers that meet certain criteria, for example, a minimal screen size, or a certain type of interface. Such criteria can also refer to the commercial side. For example, you are usually looking for suppliers who actually ship to your country and serve your type of business. Particularly unsatifying is current search when your search is based on a less common meaning of a very popular term (thanks to Peter Mika for this good example), or if you have a special requirement that most of the offers do not meet.

While search for suitable suppliers is the most obvious use case, it is by far not the only one in which current Web technology is deficient. Basically, the vast amount of product data exchange via the Web page is very unsatisfying from a data management perspective. It requires a lot of human labor for extracting and pasting data element by element from a Web page to an in-house system, and for "stupid" information processing, like unit conversion or summing up two values. While there exist standardized classification schemas for products and services like UNSPCS and eClass, and even a fully-fledged OWL variant of the latter, they cannot be used for describing your offers or your needs.

Also, operators of Web shops have a hard time keeping their description of commodity items consistent with those on the vendors' pages. Only if individual agreements are established, data can be exchanged and processed easily based on XML schemas.

In short, the potential of the Web as the largest collection of persistently published product data for better search and data exchange remains unexploited, because the structure and meaning of this data is lost in the transmission.

1.2 What Does GoodRelations Contribute?

GoodRelations is a lightweight yet sophisticated vocabulary that allows manufacturers and shop operators to express the exact meaning of their offers made on the Web in a machine-readable way. This empowers search engines to support more precise search, and partners in the value chain to automate their content integration tasks.

GoodRelations complements the eClassOWL ontology, which is the first non-toy ontology for products and services. The latest version of eClassOWL provides more than 30,000 product classes and more than 5,000 attributes for describing product features.

The relationship between these two ontologies is straightforward:

While eClassOWL is the largest ontology for products and services, one can use any other products or services ontology in combination with GoodRelations. Only a few guidelines must be met.

For example, the Austrian ebSemantics initiative is close to release several products and services ontologies for particular domains (events, tickets, accommodation, etc.) that will be GoodRelations-compliant.

There are also situations in which we cannot or do not want to refer to dedicated products or services ontologies. In that case, one can still use GoodRelations. See Recipe 2 for more details.

While GoodRelations is moderate in size, it is the outcome of about five years of work in progress, carried out at multiple institutions.

The main features of GoodRelations are as follows:


In the following, we give a minimal example of using GoodRelations, followed by a comprehensive list of typical, more complex scenarios.

2.1 Minimal Example

Let's assume the following simple scenario: "The shop at the Web page http://www.electronics.com offers to sell a single instance of a TV set that has a screen size of 30 centimeters, via this page, for 200 Euros." If we want to express that properly, we have to model three parts:

Before we proceed, we have to discuss the role of the URI http://www.electronics.com a little bit more. As long as a Web page is only being viewed in a Web browser, the same URI may be used to refer to multiple different things - http://www.electronics.com can be employed to point people

The Semantic Web requires that different things have different identifiers, so that computers can keep them apart. So we cannot use http://www.electronics.com as identifiers for all three parts (at most, we can use it for one of them). The cleanest way is to define individual identifiers for every distinct thing, and link them back via the rdfs:seeAlso property to a Web page that contains a combined description. This allows people to look up the Web page with human readable content easily without tangling items that must have separate identifiers for computer processing.

This aspect is described in more details in sections 3.3.1 and 3.3.2 of the GoodRelations Technical Report.

In the following example, we simply define new identifiers within the following namespace:


We will use the N3 notation for all subsequent examples because it allows breaking down statements into logical parts more easily than RDF/XML.

Now, in order to express the offering using GoodRelations, we have to do the following.

a) Step 1: Define the relevant name spaces and prefixes

# Base: http://www.heppnetz.de/ontologies/examples/gr#
@prefix toy:     <http://www.heppnetz.de/ontologies/examples/toy#> .
@prefix gr:      <http://purl.org/goodrelations/v1#> .
@prefix xsd:     <http://www.w3.org/2001/XMLSchema#> .
@prefix default: <http://www.heppnetz.de/ontologies/examples/gr#> .
@prefix rdfs:    <http://www.w3.org/2000/01/rdf-schema#> .
@prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix owl:     <http://www.w3.org/2002/07/owl#> .

b) Step 2: 'Choose a products and services ontology to describe the product and import GoodRelations'

In order to describe the types and features of the actual products or services being offered, you need to import and refer to a respective ontology. In real scenarios, a good choice is eClassOWL. You could also create your own vocabularies for specific types of products and their features following these instructions.

In the following, we will use a toy ontology available at


for reasons of simplicity. That ontology defines four types of products, namely the classes

toy:ComputerMouse, and

plus a few product feature attributes, like the quantitative properties hasScreenSize, hasSize, hasWeight, and hasOperatingValue; and the qualitative property hasInterfaceType plus respective pre-defined values, which are not used in here.

So we import GoodRelations and the toy ontology:

      a owl:Ontology ;
      owl:imports <http://purl.org/goodrelations/v1> , <http://www.heppnetz.de/ontologies/examples/toy> .

c) Step 3: Describe the business entity

      a gr:BusinessEntity ;
      rdfs:seeAlso <http://www.electronics.com> ;
      gr:legalName "Electronics.com Ltd."^^xsd:string.

d) Step 4: Describe all things that are being offered (not yet the offer itself, just the items)

First we say that mySony100Set is a TV set, and then we say that it is an actual TV set, not a make and model or a set of unknown instances (see section 5.2. for more details). Then we say that its screen size is defined by the value QuantitativeValueFloat_1, which holds the unit of measurement ("CMT" is the UN/CEFACT code for centimeters) and the actual amount ("30.0"). This may sound a bit complex for some readers but is caused by limitations of the OWL language. For background information, see section 3.4.2 of the GoodRelations Technical Report.

      a toy:TVSet , gr:ActualProductOrServiceInstance ;
      toy:hasScreenSize default:QuantitativeValueFloat_1.

      a gr:QuantitativeValueFloat ;
      gr:hasUnitOfMeasurement "CMT"^^xsd:string ;
      gr:hasValueFloat "30.0"^^xsd:float .

e) Step 5: Describe the offer and link the offer to the business entity making it

First, we must express that there is an offer to sell something and that what is being offered is described in TypeAndQuantityNode_1. Also, we have to attach UnitPriceSpecification_1 to specify the price:

      a gr:Offering ;
      gr:hasBusinessFunction gr:Sell ;
      gr:hasPriceSpecification default:UnitPriceSpecification_1 ;
      gr:includesObject default:TypeAndQuantityNode_1 .

Then we must say that Electronics.com is making that offer:

default:ElectronicsCom gr:offers default:Offering_1 .

Then we must say what is part of the offering. In our case it is "one piece of my TV set". In another case it could also be 500 ml of milk or 350 kg of coal, or a bundle of both. The quantity is specified by a float value for the amount and a string for the unit of Measurement as an UN/CEFACT Common Code. The code for piece or item is "C62". The full list is given in the Annex.

      a gr:TypeAndQuantityNode ;
      gr:amountOfThisGood "1.0"^^xsd:float ;
      gr:hasUnitOfMeasurement "C62"^^xsd:string ;
      gr:typeOfGood default:mySony100TVSet .

Now we must say that the price is 200 Euros per one piece of this bundle. The currency is encoded using the ISO 4217 standard (3 characters, "EUR" for Euro). C62 means one piece of the bundle.

      a gr:UnitPriceSpecification ;
      gr:hasCurrency "EUR"^^xsd:string ;
      gr:hasCurrencyValue "200.0"^^xsd:float ;
      gr:hasUnitOfMeasurement "C62"^^xsd:string .

That’s it. You have just encoded the offering from above in a machine-readable form. The complete RDF graph is shown in Figure 1 below.

RDF graph of the minimal example

Figure 1. RDF graph of the minimal example

The complete example in RDF/XML looks as follows:

<?xml version="1.0"?>
    <!ENTITY owl "http://www.w3.org/2002/07/owl#" >
    <!ENTITY dc "http://purl.org/dc/elements/1.1/" >
    <!ENTITY gr "http://purl.org/goodrelations/v1#" >
    <!ENTITY xsd "http://www.w3.org/2001/XMLSchema#" >
    <!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#" >
    <!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#" >
    <!ENTITY toy "http://www.heppnetz.de/ontologies/examples/toy#" >
    <!ENTITY protege "http://protege.stanford.edu/plugins/owl/protege#" >

<rdf:RDF xmlns="http://www.heppnetz.de/ontologies/examples/gr#"
    <owl:Ontology rdf:about="">
        <owl:imports rdf:resource="http://www.heppnetz.de/ontologies/examples/toy"/>
        <owl:imports rdf:resource="http://purl.org/goodrelations/v1"/>
    <gr:BusinessEntity rdf:ID="ElectronicsCom">
        <gr:legalName rdf:datatype="&xsd;string"
            >Electronics.com Ltd.</gr:legalName>
        <gr:offers rdf:resource="#Offering_1"/>
    <gr:ActualProductOrServiceInstance rdf:ID="mySony100TVSet">
        <rdf:type rdf:resource="&toy;TVSet"/>
        <toy:hasScreenSize rdf:resource="#QuantitativeValueFloat_1"/>
    <gr:Offering rdf:ID="Offering_1">
        <gr:hasPriceSpecification rdf:resource="#UnitPriceSpecification_1"/>
        <gr:hasBusinessFunction rdf:resource="&gr;Sell"/>
        <gr:includesObject rdf:resource="#TypeAndQuantityNode_1"/>
    <gr:QuantitativeValueFloat rdf:ID="QuantitativeValueFloat_1">
        <gr:hasValueFloat rdf:datatype="&xsd;float">30.0</gr:hasValueFloat>
        <gr:hasUnitOfMeasurement rdf:datatype="&xsd;string">CMT</gr:hasUnitOfMeasurement>
    <gr:TypeAndQuantityNode rdf:ID="TypeAndQuantityNode_1">
        <gr:amountOfThisGood rdf:datatype="&xsd;float">1.0</gr:amountOfThisGood>
        <gr:hasUnitOfMeasurement rdf:datatype="xsd;string">C62</gr:hasUnitOfMeasurement>
        <gr:typeOfGood rdf:resource="#mySony100TVSet"/>
    <gr:UnitPriceSpecification rdf:ID="UnitPriceSpecification_1">
        <gr:hasCurrencyValue rdf:datatype="&xsd;float">200.0</gr:hasCurrencyValue>
        <gr:hasUnitOfMeasurement rdf:datatype="&xsd;string">C62</gr:hasUnitOfMeasurement>
        <gr:hasCurrency rdf:datatype="&xsd;string">EUR</gr:hasCurrency>

Now, let’s query for offers of TV sets, and respective Web pages. In SPARQL, the proper query would be.

PREFIX gr: <http://purl.org/goodrelations/v1#>
PREFIX toy: <http://www.heppnetz.de/ontologies/examples/toy#>

SELECT ?offering
WHERE { ?offering rdf:type gr:Offering .
        ?offering gr:includesObject ?object .
        ?object gr:typeOfGood ?item .
        ?item rdf:type toy:TVSet .

Figure 2 shows the result to that query in Protégé. (Note that for more complicated examples later in this primer, the Protégé SPARQL query window cannot be used, since it operates only on the explicit triples, i.e., there is no reasoning. You can use Twinkle to experiment with SPARQL queries nicely.)

Result to the SPARQL Query

Figure 2. Result to the SPARQL Query

2.2 Motivating Scenarios

Now that you have seen the very basic flavor of offerings, we want to demonstrate the complexity of offers on the Web. This should explain why goodrelations is a bit more comprehensive than what has been shown above.

In the following, we describe a few typical examples of offerings made on the Web.

Scenario 1: A Web resource represents an entity that, in general, offers items of a particular kind of good for sale, either to wholesalers or to end users, or both; they might offer concrete, identifiable instances or it may be that it is only said that such instances exist.

Scenario 2: A Web resource describes the make and model of a commodity and its properties. Such Web resources are usually within the domain name space of the respective manufacturer. There may exist actual individuals of this make and model, which share the default properties defined by the make and model, but also have additional properties of their own (e.g. the date of production or the serial number).

Note: For an in-depth discussion of the semantics of makes and models, see section 3.1.5 in the GoodRelations Technical report, available at http://www.heppnetz.de/projects/goodrelations/GoodRelations-TR-final.pdf.

Scenario 3: A Web resource represents (1) the description of a particular make and model of a commodity and its properties, and (2) a concrete offer to sell unidentified instances thereof. Such Web resources are usually within the domain name space of Web shops.

Scenario 4: A Web resource represents (1) the description of a particular range of products, determined either by product classes or makes and models, and property ranges, and (2) a concrete offer to rent out unidentified instances thereof. Such Web resources are usually within the domain name space of rental agencies or Web pages of local dealers.

Scenario 5: A particular Web resource represents (1) the description of a particular range of products, determined either by product classes, makes and models, or property ranges, and (2) a concrete offer to provide a certain type of service for this range of products (e.g. maintenance, repair, disposal). Such Web resources are usually within the domain name space of local dealers.

GoodRelations is designed to support all the subtleties of such offerings, and many more, while also offering easier solutions for simple scenarios.


In the following, we give examples of how the GoodRelations ontology is to be used in typical scenarios. Since eClassOWL is pretty large and uses non-intuitive identifiers for its elements, which would make the examples hard to read, we first produce a toy products and services ontology that contains four product classes "Cellphone", "Piano", "Wine" and "Battery", and the quantitative properties "hasWeight" and "hasTalkTime". The resulting ontology is shown below.

3.1 Preliminaries: Header and Namespace Definition

First, we have to define namespace prefixes in order to keep the examples readable:

# Base: http://www.heppnetz.de/ontologies/goodrelations/examples#
@prefix gr:      <http://purl.org/goodrelations/v1#> .
@prefix xsd:     <http://www.w3.org/2001/XMLSchema#> .
@prefix default:  <http://www.heppnetz.de/ontologies/goodrelations/examples#> .
@prefix protege:  <http://protege.stanford.edu/plugins/owl/protege#> .
@prefix rdfs:    <http://www.w3.org/2000/01/rdf-schema#> .
@prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix owl:     <http://www.w3.org/2002/07/owl#> .

Then we have to import the GoodRelations ontology:

      a owl:Ontology ;
      owl:imports <http://purl.org/goodrelations/v1> .

For the following examples, we also define a toy vocabulary for products and services, because this keeps the examples short and more intuitive, as motivated above. The process is the same as in the minimal example from section 2.1.

      a owl:Class ;
      rdfs:subClassOf gr:ProductOrService .

      a owl:Class ;
      rdfs:subClassOf gr:ProductOrService .

      a owl:Class ;
      rdfs:subClassOf gr:ProductOrService .

      a owl:Class ;
      rdfs:subClassOf gr:ProductOrService .

      a owl:ObjectProperty ;
      rdfs:subPropertyOf gr:quantitativeProductOrServiceProperty .

      a owl:ObjectProperty ;
      rdfs:subPropertyOf gr:quantitativeProductOrServiceProperty .

3.2 Finding Suitable Unique Identifiers

On the Web for humans, the same page can describe both an offering and a company making the offering. This does not work on the Semantic Web. As said, you always have to define unique identifiers for distinct conceptual entities. If there exits a retrievable Web resource describing one or more of those entities, link to this resource using rdfs:seeAlso.

3.3 Step 1: Business Entity

We assume there exist three business entities, Sony AG as a manufacturer, Amazon as a mail order vendor, and Peter Miller as a small business that sells cell phones on the Web, mostly via eBay. All three maintain a company Web site at http://www.sony.com, http://www.amazon.com, http://www.peter-millers-shop.com respectively. GoodRelations provides properties for the DUNS and GLN/ILN numbers of businesses. In our example, we assume the DUNS number of Amazon to be 884745530, and the GLN/ILN number of SONY AG to be 4013675000004.

Quite clearly, other popular vocabularies (e.g. vCard or FOAF) for address details and contacts can and should be attached to the business entities, but since this is standard practice, we do not detail that in here.

The N3 code for Amazon is:

      a gr:BusinessEntity ;
      rdfs:comment "Amazon"^^xsd:string ;
      rdfs:seeAlso <http://www.amazon.com> ;
      gr:hasDUNS "884745530"^^xsd:string ;
      gr:legalName "Amazon Inc."^^xsd:string .

The N3 code for Peter Miller is:

      a gr:BusinessEntity ;
      rdfs:comment "Peter Miller"^^xsd:string ;
      rdfs:seeAlso <http://www.peter-millers-shop.com> ;
      gr:legalName "Peter Miller's Shop"^^xsd:string .

The N3 code for Sony is:

      a gr:BusinessEntity ;
      rdfs:comment "Sony AG"^^xsd:string ;
      rdfs:seeAlso <http://www.sony.com> ;
      gr:hasGlobalLocationNumber "4013675000004"^^xsd:string ;
      gr:legalName "Sony AG"^^xsd:string .

3.4 Step 2: Products and Offerings

As a next step, we have to describe the actual products or services that are being offered, and the offering – e.g., the actual business function (sell, repair, dispose, etc.) and other commercial properties.

You know from the minimal example that the basic structure of an offering is always a graph that links (1) a business entity to (2) an offering. The offering itself is linked to one or multiple type and quantity nodes and one or more price specification nodes. Each type and quantity node holds the quantity, the unit of measurement for the quantity, and the product or service that is included in the offering.

For each product or service included in the offering, we must know whether this is an actual instance (e.g. my MacBook Pro), a make and model (e.g. the brand MacBook Pro), or multiple anonymous instances (e.g. all of the MacBook Pro computers that a particular shop is selling). This distinction is explained in more detail in section 5.3 of this document.

A particular object that is advertised is then defined as rdfs:subClassOf of both the proper product class and one of the three GoodRelations classes gr:ActualProductOrServiceInstance, gr:ProductOrServiceModel, or gr:ProductOrServiceSomeInstancesPlaceholder.

We assume there is a Sony cell phone model s1234. It has a weight of 100g and runs for 120 hours. The model is described on the Web page http://www.sony.com/cellphones/s1234/.

In our case, the cell phone model is an instance of both the class default:Cellphone from the products and services ontology, and of the class gr:ProductOrServiceModel from GoodRelations for the reasons explained in sections 3.4.3 and 3.4.4 of the GoodRelations Technical Report.

The N3 code is:

      a gr:ProductOrServiceModel , default:Cellphone ;
      rdfs:comment "Sony cellphone model s1234"^^xsd:string ;
      rdfs:seeAlso <http://www.sony.com/cellphones/s1234/> ;
      default:hasTalkTime default:QuantitativeValueInteger_9 ;
      default:hasWeight default:QuantitativeValueFloat_10 .
      a gr:QuantitativeValueFloat ;
      rdfs:comment "The value node representing a weight of 100 grams"^^xsd:string ;
      gr:hasValueFloat "100.0"^^xsd:float ;
      gr:hasUnitOfMeasurement "GRM"^^xsd:string .
      a gr:QuantitativeValueInteger ;
      rdfs:comment "The node representing a time duration of 120 hours."^^xsd:string ;
      gr:hasValueInteger "120"^^xsd:int ;
      gr:hasUnitOfMeasurement "HUR"^^xsd:string .

Note that the respective UN/CEFACT Common Codes for the units of measurement are as follows:

Unit of Measurement UN/CEFACT Common Code
Hour HUR
Gram GRM

We can see how the flexible modeling of quantitative properties and the lack of ternary relations in OWL increase the size of the code; however, this should not be a very relevant issue, since most data will be generated and consumed by machines rather than humans. We are also planning an on-line conversion service that helps users generate GoodRelations data.

We should also state that the manufacturer of this cell phone model is Sony. For this, we use the gr:hasManufacturer property.

The N3 code is:

      gr:hasManufacturer default:Sony ;

Now, we want to model some explicit or implicit offerings:

a) Amazon sells bundles of this model plus two batteries via its shop. This is announced on the Web page http://www.amazon.com/cellphones/, too. The general offer is valid from July 1 - December 31, 2008.

First, we model the included objects, i.e., the actual cell phones and the actual batteries.

      a gr:ProductOrServicesSomeInstancesPlaceholder  ,  default:Cellphone ;
      gr:hasMakeAndModel default:SonyCellPhoneModel_s1234 .

      a gr:ProductOrServicesSomeInstancesPlaceholder  .  default:Battery .

The we define the offering and what it includes, and link that to the business entity Amazon. All times are given in UTC/GMT by adding the "Z" suffix to date/time values. Other time zones can be specified; see below for details.

      gr:offers default:AmazonOfferingABundle .

      a gr:Offering ;
      rdfs:comment "Amazon is offering a bundle, composed of s1234 phones and two batteries."^^xsd:string ;
      rdfs:seeAlso <http://www.amazon.com/cellphones/> ;
      gr:hasBusinessFunction gr:Sell ;
      gr:includesObject default:TypeAndQuantityNode_Amazon1 ,  default:TypeAndQuantityNode_Amazon2 ;
      gr:validFrom "2008-01-01T00:00:00Z"^^xsd:dateTime ;
      gr:validThrough "2008-12-31T23:59:59Z"^^xsd:dateTime .

What the bundle exactly includes is specified by two type and quantity nodes:

      a gr:TypeAndQuantityNode ;
      rdfs:comment "This node represents that the Amazon offering includes two batteries."^^xsd:string ;
      gr:amountOfThisGood "2.0"^^xsd:float ;
      gr:hasUnitOfMeasurement "C62"^^xsd:string ;
      gr:typeOfGood default:CellPhoneBattery_InstancePlaceholder .
      a gr:TypeAndQuantityNode ;
      rdfs:comment "This instance reflects that the Amazon offering includes 1 unit (Code C62) of the instances placeholder Cellphone_3."^^xsd:string ;
      gr:amountOfThisGood "1.0"^^xsd:float ;
      gr:hasUnitOfMeasurement "C62"^^xsd:string ;
      gr:typeOfGood default:Cellphone_3 .

b) Peter Miller sells a used instance of this model via eBay and offers to repair any Sony s1234 cell phone. This is announced on the Web page http://www.ebay.com/auction1234/ and http://www.peter-millers-shop.com/service/ respectively. Both of his offers are valid from December 1 - December 31, 2008.

Again, we first model the objects that are being offered for sale or repair:

      a gr:ActualProductOrServiceInstance  ,  default:Cellphone ;
      gr:hasMakeAndModel default:SonyCellPhoneModel_s1234 .

      a gr:ProductOrServicesSomeInstancesPlaceholder , default:Cellphone ;
      rdfs:comment "This node represents all of the anonymous cell phone instances of Sony s1234 which Peter Miller is willing to try to repair."^^xsd:string ;
      gr:hasMakeAndModel default:SonyCellPhoneModel_s1234 .

Then we model the two actual offers and what they include and link them to the business entity:

      gr:offers default:MillersOfferToRepair  ,  default:MillersOfferingEbay .

      a gr:Offering ;
      rdfs:comment "Peter Miller's Offering to sell his cell phone on eBay."^^xsd:string ;
      rdfs:seeAlso <http://www.ebay.com/auction1234/> ;
   gr:hasBusinessFunction gr:Sell ;
      gr:includesObject default:TypeAndQuantityNode_PeterEbay ;
      gr:validFrom "2008-12-01T00:00:00Z"^^xsd:dateTime ;
      gr:validThrough "2008-12-31T23:59:59Z"^^xsd:dateTime .

      a gr:Offering ;
      rdfs:comment "Peter Miller's Offering to repair Sony s1234 cell phones."^^xsd:string ;
      rdfs:seeAlso <http://www.peter-millers-shop.com/service/> ;
      gr:hasBusinessFunction gr:Repair ;
      gr:includesObject default:TypeAndQuantityNode_MillersRepair ;
      gr:validFrom "2008-12-01T00:00:00Z"^^xsd:dateTime ;
      gr:validThrough "2008-12-31T23:59:59Z"^^xsd:dateTime .

      a gr:TypeAndQuantityNode ;
      gr:amountOfThisGood "1.0"^^xsd:float ;
      gr:hasUnitOfMeasurement "C62"^^xsd:string ;
      gr:typeOfGood default:PetersUsedCellphone .

      a gr:TypeAndQuantityNode ;
      rdfs:comment "The node that represents that Peter Miller's offer to repair Sony s1234 cell phones refers to 1 cell phone. This node may become significant in combination with Unit Price Specifications."^^xsd:string ;
      gr:amountOfThisGood "1.0"^^xsd:float ;
      gr:hasUnitOfMeasurement "C62"^^xsd:string ;
      gr:typeOfGood default:AnonymousCellphoneInstancesOfTypeSony_s1234 .

c) Sony produces that model and implicitly sells instances thereof. This is announced on the Web page http://www.sony.com/cellphones/s1234/, too. The general offer is valid from January 1 - December 31, 2008.

Now, the cell phone model default:SonyCellPhoneModel_s1234 has already been defined above. What remains to be stated is that there exist unknown instances of this type of cell phone, which Sony is offering for sale. This looks as follows:

      a gr:ProductOrServicesSomeInstancesPlaceholder  ,  default:Cellphone ;
      gr:hasMakeAndModel default:SonyCellPhoneModel_s1234 .

default:Sony gr:offers default:SonyOffering_s1234_phones .

      a gr:Offering ;
      rdfs:comment "The general Sony offer to sell s1234s"^^xsd:string ;
      rdfs:seeAlso <http://www.sony.com/cellphones/s1234/> ;
      gr:hasBusinessFunction gr:Sell ;
      gr:includesObject default:TypeAndQuantityNode_Sony ;
      gr:validFrom "2008-01-01T00:00:00Z"^^xsd:dateTime ;
      gr:validThrough "2008-12-31T23:59:59Z"^^xsd:dateTime .

      a gr:TypeAndQuantityNode ;
      rdfs:comment "The node representing the fact that the general Sony offer refers to one cellphone. C62 is the common code for \"unit\"."^^xsd:string ;
      gr:amountOfThisGood "1.0"^^xsd:float ;
      gr:hasUnitOfMeasurement "C62"^^xsd:string ;
      gr:typeOfGood default:Cellphone_SomeSonys .

Note 1: GoodRelations supports time zone specifications for gr:validFrom and gr:validThrough as follows:

For a time in GMT/UTC, simply add a "Z" following the time:


Alternatively, you can specify an offset from the UTC time by adding a positive or negative time following the time:




Note 2: EAN/UCC/GTIN-13 codes for product models or product instances can be attached using the gr:hasEAN_UCC-13 property. GTIN-14 codes can be attached using the gr:hasGTIN-14 property.

3.5 Step 3: Eligible Customers and Regions

Now, let’s state that the Sony offering is for resellers only:

      gr:eligibleCustomerTypes gr:Reseller .

Also, Amazon ships the phone to Austria, Germany, and Switzerland only:

      gr:eligibleRegions "CH"^^xsd:string  ,  "AT"^^xsd:string  ,  "DE"^^xsd:string .

Peter Miller will sell to Austria and Italy only:

      gr:eligibleRegions "AT"^^xsd:string  ,  "IT"^^xsd:string .

3.6 Step 4: Price Specifications

We should now add information on the prices asked by the various vendors.

As for Peter Miller, the price for the cell phone in his fix price auction at eBay is 80 Euros including VAT. The validity of that price is from Dec 1 - Dec 31, 2008.

      gr:hasPriceSpecification default:UnitPriceSpecification_MillersCellPhone .

      a gr:UnitPriceSpecification ;
      rdfs:comment "The price specification for Peter Miller's fix-price auction."^^xsd:string ;
      gr:hasCurrency "EUR"^^xsd:string ;
      gr:hasCurrencyValue "80.0"^^xsd:float ;
      gr:hasUnitOfMeasurement "C62"^^xsd:string ;
      gr:validFrom "2008-12-01T00:00:00Z"^^xsd:dateTime ;
      gr:validThrough "2008-12-31T23:59:59Z"^^xsd:dateTime ;
      gr:valueAddedTaxIncluded "true"^^xsd:boolean .

Note that the validity of price specifications may be shorter than the validity of the offering.

Sometimes, vendors don’t give actual prices but just indicate ranges. GoodRelations supports that because it is a practical requirement, even though it is a bit problematic from the ontological perspective. Let’s assume the price for the cell phone at Amazon is a range between 50 and 99 Euros per cell phone including VAT. The validity of that price is from Dec 1 - Dec 31, 2008.

      gr:hasPriceSpecification default:UnitPriceSpecification_Amazon99 .

      a gr:UnitPriceSpecification ;
      rdfs:comment "The price specification that one unit of the bundle costs between 50 and 99 Euros including VAT."^^xsd:string ;
      gr:hasCurrency "EUR"^^xsd:string ;
      gr:hasMaxCurrencyValue "99.0"^^xsd:float ;
      gr:hasMinCurrencyValue "50.0"^^xsd:float ;
      gr:hasUnitOfMeasurement "C62"^^xsd:string ;
      gr:validFrom "2008-12-01T00:00:00Z"^^xsd:dateTime ;
      gr:validThrough "2008-12-31T23:59:59Z"^^xsd:dateTime ;
      gr:valueAddedTaxIncluded "true"^^xsd:boolean .

Sony does only publish a list price specification of 150 Euros including VAT. This is handled by the Boolean datatype property gr:isListPrice.

      gr:hasPriceSpecification default:UnitPriceSpecification_SonyListPrice .

      a gr:UnitPriceSpecification ;
      gr:hasCurrency "EUR"^^xsd:string ;
      gr:hasCurrencyValue "150.0"^^xsd:float ;
      gr:hasUnitOfMeasurement "C62"^^xsd:string ;
      gr:isListPrice "true"^^xsd:boolean ;
      gr:valueAddedTaxIncluded "true"^^xsd:boolean .

3.7 Step 5: Delivery Options and Delivery Charge Specifications

Amazon ships via DHL or Mail:

              gr:DHL  ,  gr:DeliveryModeMail .

The shipment charge via DHL is 8 Euros to Austria, Germany, and Switzerland:

      gr:hasPriceSpecification default:DeliveryChargeSpecification_3-Amazon-8EUR .

      a gr:DeliveryChargeSpecification ;
      rdfs:comment "The specification of shipment charges for the Amazon offering."^^xsd:string ;
      gr:appliesToDeliveryMethod gr:DHL ;
      gr:eligibleRegions "CH"^^xsd:string  ,  "AT"^^xsd:string  ,  "DE"^^xsd:string ;
      gr:hasCurrency "EUR"^^xsd:string ;
      gr:hasCurrencyValue "8.0"^^xsd:float ;
      gr:valueAddedTaxIncluded "true"^^xsd:boolean .

The other offerings have no information of delivery modes and respective charges.

3.8 Step 6: Payment Options and Payment Charge Specifications

Amazon accepts Visa and MasterCard:

              gr:VISA  ,  gr:MasterCard .

Peter Miller accepts payment by bank transfer in advance ("Wire tranfer") only:

              gr:ByBankTransferInAdvance .

              gr:ByBankTransferInAdvance .

Note that such must be specified for each offering individually.

3.9 Step 7: Warranty Promises

Often, an offer includes a bundle of services that will be provided free of charge in case of defects or malfunction. GoodRelations support expressing that, too.

Let’s assume Sony grants a warranty of 24 months parts and labor, customer bring-in:

              default:WarrantyPromise_Sony_24_months .

      a gr:WarrantyPromise ;
      rdfs:comment "Sony grants a warranty of 24 months parts and labor, customer bring-in."^^xsd:string ;
      gr:durationOfWarrantyInMonths "0"^^xsd:int ;
      gr:hasWarrantyScope gr:PartsAndLabor-BringIn .

Let’s assume Amazon grants a warranty of 12 months parts and labor, pick-up; and 36 months covering labor only:

              default:WarrantyPromise_5-Amazon-12months , default:WarrantyPromise_6-Amazon-36months .

      a gr:WarrantyPromise ;
      rdfs:comment "Amazon grants a warranty of 12 months parts and labor, pick-up."^^xsd:string ;
      gr:durationOfWarrantyInMonths "12"^^xsd:int ;
      gr:hasWarrantyScope gr:PartsAndLabor-PickUp .

      a gr:WarrantyPromise ;
      rdfs:comment "Amazon grants a warranty of 36 months covering labor only."^^xsd:string ;
      gr:durationOfWarrantyInMonths "0"^^xsd:int ;
      gr:hasWarrantyScope gr:Labor-BringIn .

Peter Miller grants a warranty on parts and labor for 1 month, customer bring-in.

              default:PeterMillersWarrantyPromise .

              default:PeterMillersWarrantyPromise .

      a gr:WarrantyPromise ;
      rdfs:comment "Peter Miller grants a warranty on parts and labor for 1 month, customer bring-in."^^xsd:string ;
      gr:durationOfWarrantyInMonths "1"^^xsd:int ;
      gr:hasWarrantyScope gr:PartsAndLabor-BringIn .

You see that the scope and duration needs to be defined only once, but it must be attached to each individual offering it applies to.

3.10 Step 8: Bundles

Often, vendors offer a bundle of objects at a single price. This may even require the combination of arbitrary units of measurement, e.g. "500 grams of butter, 1 m of wire, and one piece of cell phone." GoodRelations supports this inherently, because the type and quantity nodes always contain an explicit unit of measurement.

For example, assume that we offer a bundle of one piano and 0.7 liters of wine.

First, we define the objects included:

      a default:Wine ,       
      gr:ProductOrServicesSomeInstancesPlaceholder .

      a default:Piano ,  
      gr:ProductOrServicesSomeInstancesPlaceholder .

Then we define the offering and link it to two type and quantity nodes.

      a gr:Offering ;
      gr:includesObject default:TypeAndQuantityNode_OnePiano  ,  default:TypeAndQuantityNode_700mlWine .

Then we specify the quantities included in each type and quantity node.

      a gr:TypeAndQuantityNode ;
      gr:amountOfThisGood "1.0"^^xsd:float ;
      gr:hasUnitOfMeasurement "C62"^^xsd:string ;
      gr:typeOfGood default:Piano_4 .

      a gr:TypeAndQuantityNode ;
      gr:amountOfThisGood "0.7"^^xsd:float ;
      gr:hasUnitOfMeasurement "LTR"^^xsd:string ;
      gr:typeOfGood default:SomeRedWine .

Keep in mind that the UN/CEFACT Common Code for liter is " LTR" and that for "unit or piece" is "C62".

Note that this bundle offering is not yet linked to a business entity and price specification. In a real-world scenario, such would be necessary but is done exactly as demonstrated for non-bundles before. The only difference is that the only meaningful unit of measurement for price specifications of bundles is "C62" for "Unit or piece", because the price is per bundle.

3.11 Step 9: Services and Value Ranges

Now Peter Miller says that he will also repair any cell phone that weighs between 10 and 120 grams. This works simply by using gr:hasMinValueFloat and gr:hasMaxValueFloat.

      a gr:Offering ;
      rdfs:comment "Peter Miller promises to repair cell phones that weigh between 10 and 120 grams."^^xsd:string ;
      gr:hasBusinessFunction gr:Repair ;
      gr:includesObject default:TypeAndQuantityNode_Miller-CellPhoneRepair .

      a gr:TypeAndQuantityNode ;
      rdfs:comment "This node represents that Peter Miller's offer to repair refers to one unit of a cell phone."^^xsd:string ;
      gr:amountOfThisGood "1.0"^^xsd:float ;
      gr:hasUnitOfMeasurement "C62"^^xsd:string ;
      gr:typeOfGood default:Cellphone_10-AnyCellphoneThatWeighs10-120grams .

      a gr:ProductOrServicesSomeInstancesPlaceholder , default:Cellphone ;
      rdfs:comment "This entity represents anonymous instances of cellphones that weigh between 10 and 120 grams."^^xsd:string ;
      default:hasWeight default:QuantitativeValueFloat_11-WeightBetween10_and_120Gram .

      a gr:QuantitativeValueFloat ;
      rdfs:comment "This value object represents weights between 10 and 120 grams."^^xsd:string ;
      gr:hasMaxValueFloat "120.0"^^xsd:float ;
      gr:hasMinValueFloat "10.0"^^xsd:float ;
      gr:hasUnitOfMeasurement "GRM"^^xsd:string .

At first, the usage of the type and quantity node may look cumbersome for providing services, but it is important. Having the same pattern for all offerings simplifies querying a lot. Also, there are scenarios in which the business function provided relates to a combination of objects ("We clean one car and one trailer for 20 dollars").

3.12 Step 10: Shop Locations and Opening Hours

Now, let’s assume that Peter Miller’s shop, from which he provides the service described in step 9, is located in Boston and opens Mondays through Saturdays, 10:00 a.m. - 8:00 p.m. First, we say for which offers this location is relevant (only his service offers):

              default:MillersShopBoston .

              default:MillersShopBoston .

Now we define the shop location itself. Note that contact details etc. can (and should) be attached using other standardized vocabularies. Then we link it to the nodes holding the opening hours for a given day of the week.

      a gr:LocationOfSalesOrServiceProvisioning ;
              default:OpeningHoursSpecification_Sat10To8 ,  default:OpeningHoursSpecification_Fri10To8 , default:OpeningHoursSpecification_Tue10To8 , default:OpeningHoursSpecification_Wed10To8 , default:OpeningHoursSpecification_Mo-10To8  ,  default:OpeningHoursSpecification_Thu10To8 .

A gr:hasGlobalLocationNumber property could also be added here in order to hold the GLN/ILN number for a business location.

Then we define the opening hours day by day. Note that while this is a bit verbose, you have to do so only once for each shop. If you have multiple shops that are in the same time zone and have the exact same opening hours, you can also use the same opening hour specification objects for all of your locations.

      a gr:OpeningHoursSpecification ;
      gr:closes "20:00:00"^^xsd:time ;
      gr:hasOpeningHoursDayOfWeek gr:Monday ;
      gr:opens "10:00:00"^^xsd:time .

      a gr:OpeningHoursSpecification ;
      gr:closes "20:00:00"^^xsd:time ;
      gr:hasOpeningHoursDayOfWeek gr:Tuesday ;
      gr:opens "10:00:00"^^xsd:time .

      a gr:OpeningHoursSpecification ;
      gr:closes "20:00:00"^^xsd:time ;
      gr:hasOpeningHoursDayOfWeek gr:Wednesday ;
      gr:opens "10:00:00"^^xsd:time .

      a gr:OpeningHoursSpecification ;
      gr:closes "20:00:00"^^xsd:time ;
      gr:hasOpeningHoursDayOfWeek gr:Thursday ;
      gr:opens "10:00:00"^^xsd:time .

      a gr:OpeningHoursSpecification ;
      gr:closes "20:00:00"^^xsd:time ;
      gr:hasOpeningHoursDayOfWeek gr:Friday ;
      gr:opens "10:00:00"^^xsd:time .

      a gr:OpeningHoursSpecification ;
      gr:closes "20:00:00"^^xsd:time ;
      gr:hasOpeningHoursDayOfWeek gr:Saturday ;
      gr:opens "10:00:00"^^xsd:time .

Important: GoodRelations supports time zones for "opens" and "closes". If no time-zone suffix is included, the time is given in the local time valid at the location (local time, whatever that is). For a time in GMT/UTC, simply add a "Z" following the time, e.g.

gr:opens "10:00:00Z"^^xsd:time

Alternatively, you can specify an offset from the UTC time by adding a positive or negative time following the time, e.g.

gr:opens "10:00:00-09:00"^^xsd:time


gr:opens "10:00:00+09:00"^^xsd:time

3.13 Step 11: Consumables, Accessories, Spare Parts, and Similar Products

Peter Miller also sells one used battery, an accessory and a spare part for the Sony cell phone model s1234:

      a default:Battery ;
              default:SonyCellPhoneModel_s1234 .

      a gr:Offering ;
      gr:hasBusinessFunction gr:Sell ;
      gr:includesObject default:TypeAndQuantityNode_OneUsedBattery .

      a gr:TypeAndQuantityNode ;
      gr:amountOfThisGood "1.0"^^xsd:float ;
      gr:hasUnitOfMeasurement "C62"^^xsd:string ;
      gr:typeOfGood default:PetersUsedBattery .


In the following, we give examples in SPARQL on how to query respective product and services data on the Semantic Web. This section may be extended in a future version of the primer. There is also a dedicated Wiki page that will contain examples of more sophisticated queries.

4.1 Find all known business entities and their legal names

PREFIX gr: <http://purl.org/goodrelations/v1#>
SELECT ?entity ?legalname
WHERE { ?entity rdf:type gr:BusinessEntity.
        ?entity gr:legalName ?legalname. }

The query executes as expected in Protégé:

Query results to query 4.1

Figure 3. Query results to query 4.1 in Protégé

4.2 Who sells cell phones and on which Web pages can I get more information on respective offerings?

PREFIX gr: <http://purl.org/goodrelations/v1#>
PREFIX ex: <http://www.heppnetz.de/ontologies/goodrelations/examples#>
SELECT ?business ?uri
        ?business gr:offers ?offering .
        ?offering gr:includesObject ?TypeAndQuantityNode .
        ?TypeAndQuantityNode gr:typeOfGood ?something .
        ?something rdf:type ex:Cellphone .
        ?offering gr:hasBusinessFunction gr:Sell.
        ?offering rdfs:seeAlso ?uri }

The query executes as expected in Protégé:

Query results to query 4.2

Figure 4. Query results to query 4.2 in Protégé

4.3 Which offers of cell phones exists, what is the price, and where can I find the offering on the Web?

Note: Since we introduced price ranges, you must always use gr:hasMaxCurrencyValue or gr:hasMinCurrencyValue (or both) when querying for prices. gr:hasCurrencyValue is only a shortcut if the price is no range, i.e. the upper and lower bound are identical, and the reasoner will then infer that both gr:hasMaxCurrencyValue and gr:hasMinCurrencyValue will have the respective value (but not vice versa, naturally!). In most standard cases, you can simply use gr:hasMaxCurrencyValue for what we consider the price in our daily lives.

PREFIX gr: <http://purl.org/goodrelations/v1#>
PREFIX ex: <http://www.heppnetz.de/ontologies/goodrelations/examples#>
SELECT ?offering ?uri ?maxprice ?currency
WHERE { ?offering gr:includesObject ?TypeAndQuantityNode .
        ?TypeAndQuantityNode gr:typeOfGood ?something .
        ?something rdf:type ex:Cellphone .
        ?offering gr:hasBusinessFunction gr:Sell.
        ?offering rdfs:seeAlso ?uri .
        ?offering gr:hasPriceSpecification ?priceSpecification .
        ?priceSpecification rdf:type gr:UnitPriceSpecification .
        ?priceSpecification gr:hasCurrency ?currency .
        ?priceSpecification gr:hasMaxCurrencyValue ?maxprice .}

Since Protégé considers only explicit triples in the SPARQL query function, this return only one hit:

Query results to query 4.3a

Figure 5. Query results to query 4.3 in Protégé

If we change the last line in the query to

?priceSpecification gr:hasCurrencyValue ?maxprice .

the two other offerings, which specify the price using gr:hasCurrencyValue. If one uses a repository with reasoning support, the query given above will return all three results. The reason they are missing if there is no reasoner is that the triple

x gr:hasMaxCurrencyValue y .

is to be produced by the reasoner out of

x gr:hasCurrencyValue y.

Query results to query 4.3b

Figure 6. Query results to the modified query 4.3 in Protégé

Note that offerings that do not have a price specification at all do not appear in here due to the structure of the query. Such can be avoided by using the optional pattern matching support of SPARQL.

Query results to query 4.4

Figure 7. Query results to query 4.4 in Protégé


In this section, we explain some more sophisticated features of GoodRelations. For background information, please refer to the GoodRelations Technical Report. The GoodRelations Wiki will also include a growing collection of recipes for typical scenarios.

5.1 Handling of Ranges and Intervals

Most quantitative properties of products or services are actually intervals and not single point values. Even simple characteristics like the weight of a tangible object can, in principle, only be specified as intervals (even if very small).

Also, there are many scenarios in which queries for suitable products or services must allow ranges in the query and must reason properly about such ranges. For example, if someone is looking for a TV set with a screen size between 10 and 15 inches, a model with 12 inches must be reported as a match, and if someone has a piano that needs to be transported and weighs 120 kg, a company offering to transport all pianos up to a weight of 150 kg must be found.

Now, there have been approaches of extending Web ontology languages, namely OWL, by support for datatype ranges. The most prominent approach is the OWL-Eu proposal by Pan and Horrocks (Pan & Horrocks:, 2005). This would allow proper reasoning about value ranges for OWL datatype properties. However, this extension is currently not widely supported by standard tooling; it has yet to find its way into mainstream Semantic Web infrastructure. Since GoodRelations aims at making Semantic Web-based E-Commerce a reality on the basis of current technology components, using OWL-Eu was not an option for the moment.

Instead, we use a pragmatic workaround that shifts part of the work on the individual expressing the query but at the same time requires only a standard RDF-S or OWL reasoner that supports rdfs:subPropertyOf.

The approach is as follows (see Figure 8):

a) We create an ontology class Quantitative Value.

b) All properties reflecting quantitative characteristics of products or services are represented as object properties with the range of Quantitative Value.

c) For each quantitative value, we create a new instance of Quantitative Value.

d) We then attach the upper and lower limits of this value by two datatype properties (i.e. attributes) hasMinValue and hasMaxValue, and the unit of measurement by a datatype property hasUnitOfMeasurement.

Now, querying for suitable objects requires just specifying the lower and upper limits for the respective upper and lower bounds. Figure 8 illustrates this approach.

Work-around for Value Ranges

Figure 8. Work-around for Value Ranges

One may object that this means a lot of redundancy for those cases where the upper and the lower limit are practically the same. In order to mitigate this, we introduce a third datatype property hasValue, which is an rdfs:subPropertyOf both hasMinValue and of hasMaxValue.

We can then simply say

myTVSet hasWeight X
X instance of QuantitativeValue
X hasValue 10
X hasUnitOfMeasurement "kg"

As long as there is reasoner that computes the implicit fact that all triples

X hasValue Y


X hasMinValue Y and
X hasMaxValue Y,

this shortcut will return the very same results.

Note: Users of this workaround must be advised that ranges in here mean that all possible values in this interval are covered. (Sometimes, the actual commitment may be less than that: "we sell cars from 2 - 12 seats" does often not really mean that they have cars with 2,3,4,...12 seats.). Someone renting two types of rowing boats, one that fits for 1 or 2 people, and another that must be operated by 4 people cannot claim to rent boats with a seating capacity between 1 and 4 people. He or she is renting out two types of boat, one holding 1-2 and another holding 4 passengers.

In practice, we created two specializations of the classes and datatype properties described above, one for float values and one for integer values each. Figure 9 shows the respective part in Protégé.

The work-around for ranges in Protégé

Figure 9. The work-around for ranges in Protégé

The same mechanism is now also used for price ranges, see the definition of hasCurrencyValue, hasMaxCurrencyValue, and hasMinCurrencyValue.

Important Note: When querying, you must always use hasMinValue / hasMaxValue, and not the shortcut hasValue, because the reasoner will compute the identical values for the upper and lower bound when the shortcut is used, but it will not and cannot compute a value for hasValue in case an interval is specified.

5.2 Products and Services: Models, Classes, and Instances

eCl@ss, eClassOWL, and many other taxonomies for products and services don’t make the important but subtle distinction between instances and models of a type of product or service, as explained in section 3.1.5 of the GoodRelations Technical Report. In fact, eCl@ss and eClassOWL provide classes like "TV Set" and attributes like "hasScreensize" that can, in the absence of a formal definition of their semantics, be used both for describing product models (e.g. the default screen size of a particular Siemens TV set), and product instances (e.g. my actual TV set).

This is why eClassOWL products and services classes are all subclasses of a top-level class that is the union of "Product or Service Model" and "Product or Service Classes". Thus, we introduce four classes for product or services classes, instances, and models:

ProductOrService as a top-level class, and ActualProductOrService, ProductOrServiceModel, and ProductOrServicesSomeInstancesPlaceholder as subclasses of this top-level class. They are defined as follows:

owl:Class ProductOrService

The superclass of all classes describing products or services types, either by nature or purpose. Examples for such subclasses are "TV set", "vacuum cleaner", etc. All eClassOWL "gen" classes are subclasses of this class. An instance of this class can be either an actual product or service or a placeholder instance for unknown instances of a mass-produces commodity. Since eClassOWL and other large products and services ontologies are used for both describing product and services instances and product and service makes and models, this top-level concept is the union of (1) Actual Product or Service Instances, (2) Product or Service Models, and (3) ProductOrServiceSome-Instances Placeholders. The latter are "dummy" instances representing anonymous products or services instances (i.e., such that are said to exist but not actually being exposed on the Web).


a) MyCellphone123, i.e. my personal, tangible cell phone

b) Siemens1234, i.e. the Siemens cell phone make and model 123

c) dummyCellPhone123 as a placeholder for actual instances of a certain kind of cellphones.

owl:Class ActualProductOrServiceInstance

An Actual Product or Service Instance is a single identifiable object or action that creates some increase in utility (in the economic sense) for the individual possessing or using this very object (Product) or for the individual in whose favor this very action is being taken (Service). Products or Services are types of goods in the economic sense.

Examples: MyThinkpad T60, the pint of beer standing in front of me, my Volkswagen Golf, the haircut that I received or will be receiving at a given date and time.

Note: In many cases, product or service instances are not explicitly exposed on the Web but only existentially quantified. For a detailed discussion and practical solutions, see section 3.3.3. of the Technical Report.

owl:Class ProductOrServiceModel

From the ontological perspective, a Product or Service Model is an intangible entity that specifies some characteristics of a group of similar, usually mass-produced Products. In case of mass-produced Products, there exists a relation hasMakeAndModel between the Products and Services Instance and the Product or Service Model. However, since eClassOWL and other products and services ontologies don't support this important disctinction, Product or Service Models are a subclass of Product or Service in GoodRelations.

Examples: Ford T, Volkswagen Golf, Sony Ericsson W123 cellphone

owl:Class ProductOrServicesSomeInstancesPlaceholder

A placeholder instance for unknown instances of a mass-produces commodity. This is used as a computationally cheap workaround for such instances that are not individually exposed on the Web but just stated to exist (i.e., which are existentially quantified).

Example: An instance of this class can represent an anonymous set of green Siemens1234 phones. It is different from the ProductOrServiceModel Siemens1234, since this refers to the make and model, and it is different from a particular instance of this make and mode (e.g. my individual phone) since the latter can be sold only once.

The GoodRelations ontology in OWL uses these four classes for products and services in order to maximize compatibility with existing products and services ontologies. Figure 10 shows the resulting subsumption hierarchy. Indicated in yellow are the GoodRelations language elements. Shown in green is an example of a products and services class. Shown in blue are examples of an actual product instance, a make and model, and a placeholder for unknown (but existentially quantified) instances.

Figure 10. The GoodRelations ontology in OWL uses four classes for products and services in order to maximize compatibility with existing products and services ontologies.

An key reason for this modeling workaround is the large amount of properties for product characteristics that are part of eCl@ss and eClassOWL, with more than 5,000 precisely defined elements for all kinds of aspects. Properly separating products from models, as described in the domain capture in section 3.1.5 of the GoodRelations Technical Report, and as would follow from OntoClean (Guarino & Welty, 2002 and 2004) would force us to duplicate both the hierarchy of categories of eCl@ss (now more than 30,000 categories) and the properties (more than 5,000), which is unfeasible. Quite clearly, we need to be able to specify e.g, screen sizes for both models and instances, but a model does not have a screen size in the same way an instance has a screen size. The semantics of screen size attached to a model implies that an actual product that is of the respective make and model will (likely) have the respective screen size (see section 3.1.5 of the GoodRelations Technical Report for details).

When annotating an entity, we can then be more specific and say that the entity is either a model or a product or a placeholder for anonymous instances. The difference between actual instances, models, and anonymous instances of a product or service is then expressed by making a particular object the intersection of both the product category and one of the three subclasses of gr:ProductOrService.


GoodRelations relies on the UN/CEFACT Common Codes for specifying unit of measurement.
The normative list is available at http://www.unece.org/cefact/recommendations/rec20/Rec20_Rev6e_2009.xls

For your convenience, this document includes a list of the most popular codes.

UN/CEFACT Common Code Unit of Measurement
28 kg/m²
2N dB
4H µm
4P N/m
A24 cd/m²
A86 GHz
A94 g/mol
B22 kA
B32 kg • m2
B43 kJ/(kg.K)
B49 kΩ
B61 lm/W
BAR bar
C16 mm/s
C24 mPa.s
C26 ms
C45 nm
C62 1
C65 Pa.s
C91 1/K
C94 min-1
CDL cd
CMQ cm³
CMT cm
D33 T
D52 W/K
D74 kg/mol
DD °
E01 N/cm²
E32 l/h
GM g/m²
KGM kg
KGS kg/s
KL kg/m
KMQ kg/m³
L2 l/min
LUM lm
LUX lx
MBR mbar
MIN min
MMK mm²
MMQ mm³
MMT mm
MQH m3/h
MQS m³/s
MTS m/s
NU N • m
NU N.m
P1 %