tag:blogger.com,1999:blog-314163652024-02-03T05:45:53.599-08:00Composing the Semantic WebA tool developer's blog on ontology development for the Semantic Web and beyond.Holger Knublauchhttp://www.blogger.com/profile/13180242480924209321noreply@blogger.comBlogger111125tag:blogger.com,1999:blog-31416365.post-32214802694706348682013-07-07T19:58:00.000-07:002013-07-07T19:58:33.253-07:00Performing side effects after each edit in TopBraid EVNTopBraid 4.3 introduces a small Event-Condition-Action (ECA) rule engine that can be used to trigger rules whenever a change was performed on an EVN vocabulary or ontology. Example use cases of this feature include anything that needs to happen as a side effect of edit operations: updating an external index (such as Solr), creating automatically generated triples, aligning inverse properties, sending automated notifications to co-workers etc.<br />
<br />
Let me introduce this feature with an example rule definition. The rule below inserts an rdfs:comment whenever a new owl:DatatypeProperty has been created by someone.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiv6f0a0GGHs54bI3Mz3pTcb6dcU-y2zFZCgllOmHEzZ4G5R22h6oV7tKI8W8Ev0qu_W1WMeQXjGsx02oT7wCLwbXFn-zSjJdK6hBe7capCRxX7M4XwkGcRZA-I6g7wxpbWT4KCaw/s1600/Example-EditRule.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="325" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiv6f0a0GGHs54bI3Mz3pTcb6dcU-y2zFZCgllOmHEzZ4G5R22h6oV7tKI8W8Ev0qu_W1WMeQXjGsx02oT7wCLwbXFn-zSjJdK6hBe7capCRxX7M4XwkGcRZA-I6g7wxpbWT4KCaw/s400/Example-EditRule.PNG" width="400" /></a></div>
As shown above, these ECA rules are essentially SWP elements that define their behavior is their ui:prototype. To create your own rule, simply create a globally registered .ui.* file that imports the teamworkrules system ontology, and then create a subclass of teamwork:EditRules. The rule engine of EVN will execute the ui:prototype of any globally registered edit rule after each edit. During the execution of those prototypes, there are two dedicated named graphs with a special meaning: The graph ui:addedGraph will contain the newly added triples, and ui:deletedGraph will contain those triples that have just been deleted. For example, if someone has pressed Save Changes on an EVN form, replacing one skos:altLabel with another, then the ui:addedGraph will contain the new value, and ui:deletedGraph will contain the old value. You can use SPARQL to query those change triples and perform side effects with ui:update or SPARQLMotion modules.<br />
<br />
EVN uses this rule engine out of the box to update a Solr index after each edit (if Solr has been activated for the current project). The implementation of this Solr updater rule is shown below.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjP7BFPWePgCMILMkrnpPBprxyJb0aN_ARbFW3tUBzbQAN_ggL-zuGIwuWXkbCDjaQMSQl4PPkO89NwQfErXUC-3jkO8M0ltLru-OrCn0iFr67EsaE8hp_5G2MCZ7WnIRZ-g4f64Q/s1600/Solr-EditRule.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjP7BFPWePgCMILMkrnpPBprxyJb0aN_ARbFW3tUBzbQAN_ggL-zuGIwuWXkbCDjaQMSQl4PPkO89NwQfErXUC-3jkO8M0ltLru-OrCn0iFr67EsaE8hp_5G2MCZ7WnIRZ-g4f64Q/s400/Solr-EditRule.PNG" width="400" /></a></div>
As this blog may be out of date when you read it, you can find the current implementation of this rule in the file teamworkrules.ui.ttlx. Note that this rule has a guard clause in the first ui:if statement, to make sure that the rule only fires for the master graph, i.e. the tag/working copy must be unbound. If this condition is true, then a helper SPIN template is called that will deliver all subjects that have been mentioned in the current change:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBcCfQLJNvYcsy7XqfiysXVhqPu5jAY2wc8heKw_EBalXYZEP-R5qqIN06ZfOj57yqvmrVTd0ALyJYHwwCBJW6Ewqg4iw-btYDv9DZJQsbpWesX-2MoJdJOHrGJjNbmI4-Bhr65Q/s1600/Solr-EditRule-Template.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBcCfQLJNvYcsy7XqfiysXVhqPu5jAY2wc8heKw_EBalXYZEP-R5qqIN06ZfOj57yqvmrVTd0ALyJYHwwCBJW6Ewqg4iw-btYDv9DZJQsbpWesX-2MoJdJOHrGJjNbmI4-Bhr65Q/s400/Solr-EditRule-Template.PNG" width="335" /></a></div>
<br />
It is possible to distinguish between normal edit operations (teamwork:EditRule) and commit operations, in which a working copy has been merged into the master copy of an EVN project (teamwork:CommitRule).Holger Knublauchhttp://www.blogger.com/profile/13180242480924209321noreply@blogger.com0tag:blogger.com,1999:blog-31416365.post-24128047575192563032013-06-30T23:28:00.001-07:002013-06-30T23:28:48.076-07:00Creating Web Services with the TopBraid Platform<a href="http://www.topquadrant.com/products/TB_Live.html">TopBraid Live (TBL)</a> is TopQuadrant's server platform for semantic data processing and editing. In addition to being the foundation of various out-of-the-box solution packages such as EVN, TopBraid Live can also be used "stand-alone". The features of the platform can be accessed in various ways, for example via a built-in SPARQL end point. In addition to those bundled web services, TopBraid Live can also host any number of custom web services created by users/administrators. This blog entry enumerates a few options on how to create such web services.<br />
<br />
Common to all TopBraid custom web services is that they can be called either via GET or POST requests, and that they are created declaratively: the web services are stored in RDF and typically created with TopBraid Composer. This ensures that web services are seamlessly integrated with the data models/ontologies that they expose. Changes to an ontology will automatically update the web services etc. Furthermore, no "programming" in the traditional sense is needed to create those services.<br />
<br />
<h3>
SPARQLMotion</h3>
<a href="http://sparqlmotion.org/">SPARQLMotion</a> is an RDF-based scripting language with a graphical notations. SPARQLMotion scripts are data processing pipelines that can take some input (e.g. web service arguments), import and aggregate data from external sources, perform some processing (SPARQL etc) and export results in various formats. I had written about creating web services as early as <a href="http://composing-the-semantic-web.blogspot.com.au/2008/03/creating-web-services-with-sparqlmotion.html">2008</a> but my colleagues have since then created much better <a href="http://www.topquadrant.com/products/SPARQLMotion.html">tutorials</a> on this topic. Note that SWP (see below) provides an alternative syntax for exposing SPARQLMotion functionality as web services.<br />
<br />
<h3>
SPIN Templates</h3>
In a nutshell, a <a href="http://composing-the-semantic-web.blogspot.com.au/2009/01/understanding-spin-templates.html">SPIN Template</a> is a SPARQL query that can take parameters which are mapped to pre-bound variables. A template is a bit like a stored procedure from SQL databases in that it encapsulates a complex query and gives it a name. Here is an example SPIN Template that provides information about the properties of a given class. The class itself comes in as an argument (arg:class) which is mapped to the pre-bound variable ?class in the body of the template.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQRHVcxWoyx-s3BUSG3QWfiL5487xAevYDycnEctvexpsISxWIBjxa9mF0aFGuXThSGodmxeMtNA-475IFwLZ9crJE6fwJ8fXPBQT7GUcAuN2Fw1eX1-thsM0gMg5ZF4bNNbtrfQ/s593/swa_GetRelevantPropertiesOfClass.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQRHVcxWoyx-s3BUSG3QWfiL5487xAevYDycnEctvexpsISxWIBjxa9mF0aFGuXThSGodmxeMtNA-475IFwLZ9crJE6fwJ8fXPBQT7GUcAuN2Fw1eX1-thsM0gMg5ZF4bNNbtrfQ/s400/swa_GetRelevantPropertiesOfClass.png" width="396" /></a></div>
Any SPIN Template saved in a .spin.* file can be called as a web service, via the tbl/template servlet. The following example calls the template above against the personal test server bundled with TopBraid Composer ME:<br />
<br />
http://localhost:8083/tbl/template?<br />
_template=http://topbraid.org/swa%23GetRelevantPropertiesOfClass&<br />
_base=http://topbraid.org/examples/kennedys&<br />
class=http://topbraid.org/examples/kennedys%23Person&<br />
_format=application/sparql-results%2Bjson<br />
<br />
The parameter _base points at the default query graph (if required) and _format can be any of the <a href="http://www.w3.org/TR/sparql11-overview/">SPARQL result set formats</a> including CSV, TSV, XML and JSON.<br />
<br />
TopBraid 4.3 introduces another simpler result format, called JSON-simple, which is easy to handle by clients. Example output from the query above in JSON-simple is shown here:<br />
<br />
<span style="font-size: x-small;">[ { "propertyLabel" : "MI" ,<br /> "propertyURI" : "http://topbraid.org/examples/kennedys#middleInitial" ,<br /> "rangeURI" : "http://www.w3.org/2001/XMLSchema#string"<br /> },<br /> { "propertyLabel" : "alma mater" ,<br /> "propertyURI" : "http://topbraid.org/examples/kennedys#almaMater" ,<br /> "rangeURI" : "http://topbraid.org/examples/kennedys#College"<br /> },</span><br />
<span style="font-size: x-small;"> ...</span><br /><br />
Also new in TopBraid 4.3 is syntactic sugar that makes the query URLs easier to write:<br />
<br />
http://localhost:8083/tbl/template/swa/GetRelevantPropertiesOfClass/kennedys?<br />
class=http://topbraid.org/examples/kennedys%23Person<br />
<br />
More information on this topic can be found in the TBC help, under "TopBraid Live Integration".<br />
<br />
<h3>
SWP Services</h3>
<a href="http://uispin.org/">SPARQL Web Pages (SWP)</a> is probably best known for its ability to create HTML renderings of RDF data, but it can also produce any other textual serialization including JSON or XML. An SWP web service looks almost like a SPARQLMotion or SPIN template service in that it is a class that declares the arguments as spl:Arguments. However, SWP services also need to declare their result type, e.g. ui:JSON as value of the ui:responseType property. Here is the upper part of an example SWP web service that produces some JSON consumed by the SWA tree component:<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9m4fIHNHDEILvRqd9KvMuCMBUZkXXbStpkq9tTAT9JrrJgTBSnoS7KGlq604SDKFz4q0tZ464hKntY1qCDjhHsvlt84330DJ43qIU7boI2BRCm1Rc9sWkd9F9HHv4pzJssxcbJw/s739/SWA-Service-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="193" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9m4fIHNHDEILvRqd9KvMuCMBUZkXXbStpkq9tTAT9JrrJgTBSnoS7KGlq604SDKFz4q0tZ464hKntY1qCDjhHsvlt84330DJ43qIU7boI2BRCm1Rc9sWkd9F9HHv4pzJssxcbJw/s400/SWA-Service-1.png" width="400" /></a></div>
<br />
(The ui:responseType of that service is "inherited" from the superclass ui:JSONServices.) The actual work that the service has to perform when called is declared in the lower section of that service definition:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtOXoZed9inRYw1x6W-1xT_JL2Vw3sP9_TpXkoN9BTrjGHrGzGfTZuYpXObW4Q_ZyJ_QXcaJ-s5-5p56WDoE3tSrPXkKWlpi7RWGVj9yNXY6kRPOcNZQ7hn4rzLekzV3EzVJXnmQ/s738/SWA-Service-2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="238" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtOXoZed9inRYw1x6W-1xT_JL2Vw3sP9_TpXkoN9BTrjGHrGzGfTZuYpXObW4Q_ZyJ_QXcaJ-s5-5p56WDoE3tSrPXkKWlpi7RWGVj9yNXY6kRPOcNZQ7hn4rzLekzV3EzVJXnmQ/s400/SWA-Service-2.png" width="400" /></a></div>
<br />
This particular service is using some helper template to compute the shortest path from a given node to a given root, and then serializes the whole result set to a JSON array using the built-in helper element swon:RSArray. SWP is much more powerful than SPIN templates because it includes sophisticated control elements such as if-then-else and forEach. Furthermore, SWP services can also include most of the SPARQLMotion modules in a compact textual notation.<br />
<br />
To learn more about SWP services, browse through some of the examples bundled with TopBraid. As of TopBraid 4.3 (beta 2), the TopBraid Live Web Services overview page shown below lists all available SPARQLMotion, SPIN or SWP services - the page itself is generated on the fly using SWP:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgy8fJNs1GvGlh_tRQJlrhB2-xZ16ofETmD5MhfVe7uXkv_7bdpV6HSsZW2yKBYj9_L_ky2KfuJ_3rWEukQw4CzOrveWlmyLv_cU2XUsRF8B_Y_zVyiGCc-i8n0DEIOtFEb0nUyrA/s769/Services-Doc.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="293" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgy8fJNs1GvGlh_tRQJlrhB2-xZ16ofETmD5MhfVe7uXkv_7bdpV6HSsZW2yKBYj9_L_ky2KfuJ_3rWEukQw4CzOrveWlmyLv_cU2XUsRF8B_Y_zVyiGCc-i8n0DEIOtFEb0nUyrA/s400/Services-Doc.png" width="400" /></a></div>
<br />
<h3>
Saved Searches</h3>
TopBraid EVN includes a powerful search form that can be used to filter instances of a given class by some properties, for example to find "All Islands that have a size smaller than 1000 square kilometres":<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeDrr3GJQPf3a3Die0ZppmZFNzXdfz212qLJH2jOjyy5YAyI3ozPReHWx_29-a8tPStGV-sB4vFs3NbeC6yQ_j3gAOiomkijDHBgqlTClCeQvdiRiI9w7l0uSgP_Vi4uSmRstiDg/s478/EVN-Search-Form.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeDrr3GJQPf3a3Die0ZppmZFNzXdfz212qLJH2jOjyy5YAyI3ozPReHWx_29-a8tPStGV-sB4vFs3NbeC6yQ_j3gAOiomkijDHBgqlTClCeQvdiRiI9w7l0uSgP_Vi4uSmRstiDg/s400/EVN-Search-Form.png" width="358" /></a></div>
There is a little Save button under the search form, allowing users to save the current search form so that it can be restored later. As a side effect, any of those saved searches can also be called as a web service with the URL provided by the dialog as shown below:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfGItDo80Zh90L1PjzqtbNg22vQsv51rVYBwi0TuV33Pbqe9lABDeNnSvVXAhT5F3ILIX2r7qWOgx6rCGCExQ9GkIoeJdnn1Dlw5B_W7OmCXuyhRTpUcAiLyQFf6MdyMMd-990bw/s498/EVN-Restore-Form.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="248" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfGItDo80Zh90L1PjzqtbNg22vQsv51rVYBwi0TuV33Pbqe9lABDeNnSvVXAhT5F3ILIX2r7qWOgx6rCGCExQ9GkIoeJdnn1Dlw5B_W7OmCXuyhRTpUcAiLyQFf6MdyMMd-990bw/s400/EVN-Restore-Form.png" width="400" /></a></div>
<br />
You can copy and paste the URL of the service from the dialog above, and it may produce any of the standard result formats.Holger Knublauchhttp://www.blogger.com/profile/13180242480924209321noreply@blogger.com0tag:blogger.com,1999:blog-31416365.post-9907698559697917622013-06-18T17:07:00.003-07:002013-06-18T17:07:57.732-07:00SPIN Vocabulary for Column MetadataWhen we started implementing the <a href="http://semanticweb.com/semantic-case-study-epim-reportinghub_b26590">EPIM ReportingHub</a> project, we had to come up with a mechanism that allows us and others to represent tabular reporting data derived from an RDF triple store. For example, there needed to be a table that lists drilling fluid information at certain depths over time. We decided to represent those tables as parameterized SPARQL SELECT queries, and in particular as <a href="http://composing-the-semantic-web.blogspot.com.au/2009/01/understanding-spin-templates.html">SPIN Templates</a>. This made it possible to assemble reports consisting of multiple tables quickly. However, we noticed that a SELECT query does not provide enough information to render the tables nicely, for example to specify the text that shall appear in the header of a column or the relative widths of each column. We had added some custom properties to capture such column metadata with each SPIN template. Using this metadata, our report generator was enabled to print prettier tables.<br />
<br />
TopBraid 4.3 introduces this as a generalized feature. I have added a couple of new classes and properties to the SPIN Modeling Vocabulary itself, because I believe this will be of general interest. The extension is now online as the <a href="http://spinrdf.org/spin.html#spin-columns">SPIN Column Metadata</a> specification.<br />
<br />
In a nutshell, each SPIN SELECT Template can now point to one or more instances of the new class spin:Column, and each spin:Column may define a human-readable label, a width, and a column type. Here is an example of how such column can be entered with TopBraid 4.3:<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBWh7BhmyUgjpySYllEkUifPn-9x0m6K6pSh0Kz5b4sLQRdfarx3HRJNNTa0lX0udy3pm1jG9C-jRiwBi9Lx6fGq_P2lIouqdcIJGjpsAOd_xLhX5R4vx2O9vN4WuwgGzVoyZ58Q/s1600/spin-column-children-overview.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="308" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBWh7BhmyUgjpySYllEkUifPn-9x0m6K6pSh0Kz5b4sLQRdfarx3HRJNNTa0lX0udy3pm1jG9C-jRiwBi9Lx6fGq_P2lIouqdcIJGjpsAOd_xLhX5R4vx2O9vN4WuwgGzVoyZ58Q/s400/spin-column-children-overview.png" width="400" /></a></div>
Drilling down into the values of spin:column, we can see that each spin:Column is a blank node with an index and several other optional properties. In TopBraid, use "Create blank node..." to add new columns:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgp7mYzlScRDmDa1T-SVrlrQTnvRjwcBzn9dg2C6xJsLx5r7WzUBUw29EDFYi1dJO8nhvJdlFnTrmSCLXGwYxKiyR7pQRjSVkPZCtvshBm8cBwXqX8DnSlWdzyQyMwDMbpjQP4T7g/s1600/spin-column-children-overview-details.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgp7mYzlScRDmDa1T-SVrlrQTnvRjwcBzn9dg2C6xJsLx5r7WzUBUw29EDFYi1dJO8nhvJdlFnTrmSCLXGwYxKiyR7pQRjSVkPZCtvshBm8cBwXqX8DnSlWdzyQyMwDMbpjQP4T7g/s400/spin-column-children-overview-details.png" width="382" /></a></div>
<br />
An example rendering of such a table using the swa:ResultSetGrid component of the <a href="http://composing-the-semantic-web.blogspot.com.au/2012/07/swp-application-component-library-swa.html">SWP Application Component Library (SWA)</a> is shown below:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOhw6D_Za3OKDQVJesuuLNaFrl1crlS1gx1a3KciOtGT8z-dqI6q4lVd5mk6NVvVAadvyXUFz367p4N3E01OZUsJvDaBHG_9gsvpUlOfJUDKwA278QkL2REsD4t5nA0xLWUeU6Pw/s1600/spin-column-example.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOhw6D_Za3OKDQVJesuuLNaFrl1crlS1gx1a3KciOtGT8z-dqI6q4lVd5mk6NVvVAadvyXUFz367p4N3E01OZUsJvDaBHG_9gsvpUlOfJUDKwA278QkL2REsD4t5nA0xLWUeU6Pw/s1600/spin-column-example.png" /></a></div>
The code to produce such a table with SWP is very compact:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZESfdZtYUaTSJsaZLm_mHcl0S-d3B_NMyVahvj9-7zlxqP0dGVRyXcKZgLCmBgsh5Uc0yTNVNU5Z4qGI53dz6g-N8R8VBLX0qXnKpuG7u68gxF3mmJZvMGworq59zMSTN06UZyA/s1600/spin-column-children-overview-table.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="236" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZESfdZtYUaTSJsaZLm_mHcl0S-d3B_NMyVahvj9-7zlxqP0dGVRyXcKZgLCmBgsh5Uc0yTNVNU5Z4qGI53dz6g-N8R8VBLX0qXnKpuG7u68gxF3mmJZvMGworq59zMSTN06UZyA/s400/spin-column-children-overview-table.png" width="400" /></a></div>
<br />
When you instantiate a SPIN template with ui:call, the produced result set will carry any column metadata around, and the functions of the <a href="http://spinrdf.org/spr.html">SPR namespace</a> can be used to discover the metadata dynamically. For example, use spr:colName(?rs, 0) to get the name of the first column, or spr:colWidth(?rs, 0) to get its width.<br />
<br />
Since all this metadata is represented in RDF, it goes without saying that anyone can query it using SPARQL and repurpose the metadata for different tools such as 3rd party reporting frameworks. The extensible nature of RDF also means that anyone is free to add extra properties such as the unit of measurement of a column or the property that it has been derived from.Holger Knublauchhttp://www.blogger.com/profile/13180242480924209321noreply@blogger.com0tag:blogger.com,1999:blog-31416365.post-53767907011522527982013-06-17T22:23:00.001-07:002013-06-17T22:23:49.323-07:00Defining SPARQL Functions with SWPOne of the best kept secrets about <a href="http://spinrdf.org/">SPIN</a> is its ability to define <a href="http://composing-the-semantic-web.blogspot.com.au/2009/01/understanding-spin-functions.html">new SPARQL functions</a> that encapsulate complex sub-queries into reusable building blocks. Normal SPIN functions are limited to whatever can be expressed in SPARQL, by means of a nested spin:body query. TopBraid has extended this idea by allowing functions with other implementations yet the same general RDF vocabulary. TopBraid users have been able to define new functions using <a href="http://composing-the-semantic-web.blogspot.com.au/2009/09/currency-conversion-with-units-ontology.html">SPARQLMotion</a> and even <a href="http://composing-the-semantic-web.blogspot.com.au/2009/03/using-javascript-to-define-sparql.html">JavaScript</a> for several years.<br />
<br />
TopBraid 4.3 adds the ability to define new SPARQL functions using <a href="http://www.topquadrant.com/swp/">SPARQL Web Pages</a> (SWP). SWP is better known for its role in generating HTML, yet it also acts as a general expression language for procedural programming. SWP includes control elements such as ui:if/ui:else and ui:forEach and even the ability to invoke SPARQLMotion modules, and all that with a compact textual notation.<br />
<br />
Here is an example SWP function that gets the current exchange rate between two given currencies using the <a href="http://currency2currency.org/">currency2currency.org</a> web service:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9io3gXVgPeesYl8IRCVwikCHiAno1y2oMAnjLEitqHeVHT8dk1B6cecbibqrDPvKKxBnlpjVgUrNQn5ixbDP7JEcd9gLRimdbZz6wi23OPXmC91kb6O-HuaChGwyjABcXSk03Ig/s1600/c2c-function.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="275" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9io3gXVgPeesYl8IRCVwikCHiAno1y2oMAnjLEitqHeVHT8dk1B6cecbibqrDPvKKxBnlpjVgUrNQn5ixbDP7JEcd9gLRimdbZz6wi23OPXmC91kb6O-HuaChGwyjABcXSk03Ig/s400/c2c-function.png" width="400" /></a></div>
<br />
SWP functions look almost exactly like SPIN functions, only that they have the type ui:Function and use a ui:prototype instead of a spin:body. The prototype will be evaluated with the function arguments as pre-bound variables (shown in bold-face above). The new element ui:return can be used to return the resulting RDF node. An example call is shown below:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiu-UVfl2R24to9lNmXd6QWDN1E76_CG7D1m5jboPARiJj6ISsewKcNPismyqyD6jzilQuXxW0w6SEZS-nP4ocAq8O1cJrZ00K5YEoBgOURsf0NYoiSb9F3idDN_AnqrzsztqTmCQ/s1600/c2c-result.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="116" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiu-UVfl2R24to9lNmXd6QWDN1E76_CG7D1m5jboPARiJj6ISsewKcNPismyqyD6jzilQuXxW0w6SEZS-nP4ocAq8O1cJrZ00K5YEoBgOURsf0NYoiSb9F3idDN_AnqrzsztqTmCQ/s400/c2c-result.png" width="400" /></a></div>
<br />
Instead of using ui:return, SWP functions can also simply produce any text, and the resulting text elements will be concatenated into the function result. This is illustrated in the following example:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-PyMwnPLrD5Qrf8NF4d1PTvsshVkMK-excBN7bCvStvEWHyZgYW07GO3VWMHmkCxf8kNYjcx0awybkMJOkNmtgUxp37MFdtWPg9Gwg7GMq9Z5wglDznYc8mzAT5dhiJwFC1MGsg/s1600/ex-person-summary.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="256" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-PyMwnPLrD5Qrf8NF4d1PTvsshVkMK-excBN7bCvStvEWHyZgYW07GO3VWMHmkCxf8kNYjcx0awybkMJOkNmtgUxp37MFdtWPg9Gwg7GMq9Z5wglDznYc8mzAT5dhiJwFC1MGsg/s400/ex-person-summary.png" width="400" /></a></div>
An example call sequence is shown below:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_aTI5aKpBeTQ0p-TvDoo5i3lagAdfab9hYrRBFQ2E81VZN6z9KzvnR08F-AQmwxmfxBu09ivOc_QcyPC8zdQEKIjP5L02rzVDsqc420o3UUkXlQefCrTD3Bh7p7J_TWFpN-efVA/s1600/ex-person-summary-results.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_aTI5aKpBeTQ0p-TvDoo5i3lagAdfab9hYrRBFQ2E81VZN6z9KzvnR08F-AQmwxmfxBu09ivOc_QcyPC8zdQEKIjP5L02rzVDsqc420o3UUkXlQefCrTD3Bh7p7J_TWFpN-efVA/s400/ex-person-summary-results.png" width="400" /></a></div>
<br />
SWP functions are a more powerful alternative to normal SPIN functions, especially if the business logic is too complex to express with SPARQL alone, if SPARQLMotion callbacks are needed, or if the function's result consists of text that is easier constructed with SWP's rich text generation capabilities.Holger Knublauchhttp://www.blogger.com/profile/13180242480924209321noreply@blogger.com0tag:blogger.com,1999:blog-31416365.post-43770133930660586892013-06-13T16:52:00.000-07:002013-06-13T17:12:33.280-07:00An Extended Turtle FormatSeveral RDF/OWL ontologies use blank node structures to represent complex objects. For example, OWL uses blank nodes to represent class expression trees consisting of intersections, unions and restrictions. Other ontologies use "reified" objects that combine a value with a unit of measurement. SPIN uses blank nodes to represent SPARQL queries that are attached to classes as rules and constraints. SWP uses blank nodes to represent HTML snippets that are attached to classes as instance views.<br />
<br />
In common to all of those blank node structures is that they look ugly and unpredictable in RDF files. Here is an example class with an SWP blank node in Turtle notation:<br />
<br />
<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;">schema:Person</span></span><br />
<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> a owl:Class ;<br /> rdfs:label "Person"^^xsd:string ;<br /> rdfs:subClassOf owl:Thing ;<br /> ui:instanceView<br /> <span style="font-size: x-small;"></span>[ a html:Div ;<br /> <span style="font-size: x-small;"></span>default:subject spin:_this ;<br /> ui:child<br /> <span style="font-size: x-small;"></span>[ a swa:Object ;<br /> arg:predicate schema:familyName ;<br /> ui:childIndex 1<br /> ] ;<br /> ui:child<br /> <span style="font-size: x-small;"> </span> [ a swa:Object ;<br /> arg:predicate schema:givenName ;<br /> ui:childIndex 0<br /> ]<br /> ] ;</span></span><br />
<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;">.</span></span><br />
<br />
Even in this simple example you can see that nobody would want to edit such files per hand, and the use of automated diffing tools to compare versions will be hard because the serialization may be different each time - Turtle doesn't know anything about ui:childIndex for example, and as a result the surrounding blank nodes may be moved to different places each time. Look at any more complex file and you will see how ugly those structures can become...<br />
<br />
Many years ago I used this blog to brainstorm about a <a href="http://composing-the-semantic-web.blogspot.com.au/2006/11/plug-in-mechanism-for-n3turtle.html">plug-in mechanism for Turtle</a>. I never got around to implement this idea until this year when I had enough user feedback to confirm that people do want to be able to edit SWP files by hand, and especially want a format that allows them to use off-the-shelf versioning systems. So for for TopBraid 4.3 I have added a new format called Extended Turtle (*.ttlx) that looks like the following:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: x-small;">schema:Person</span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: x-small;"> a owl:Class ;</span></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: x-small;"><br /> rdfs:label "Person"^^xsd:string ;<br /> rdfs:subClassOf owl:Thing ;</span></span><br /> ui:instanceView """</span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: x-small;"><div default:subject=\"{= ?this }\">
<br /> <swa:Object arg:predicate=\"{= schema:givenName }\"/><br /> <swa:Object arg:predicate=\"{= schema:familyName }\"/><br /></div>
"""^^ui:Literal ;</span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: x-small;">.</span></span><br />
Extended Turtle uses a pre-processor that turns certain blank node structures into literals and a post-processor that parses the literals back into blank nodes as part of the loading. I have currently only implemented this idea for SWP expressions, but it applies to any blank node structure that also has a parsable text notation. For OWL this would be the Manchester Syntax, for SPIN it would be SPARQL text syntax, and for SWP it is the XML tag syntax. The post-processor simply looks at all literals that have a special datatype (here: ui:Literal) and runs the text parser over those. If this idea was ever considered for standardization, a minimum implementation could require that the datatype (here: ui:Literal) resolved to a web service that takes the literal and the prefixes as input and returns a valid Turtle blank node snippet. Obviously, real-world engines would want to have this parsing done client-side, as plugins to the Turtle parser (and this is what TopBraid does).<br />
<br />
One advantage of this notation is that the files are still valid Turtle, so that parsers that do not have those plugins can at least display something. In any case, the main goal of this work was to address the SWP serialization issue and I believe the solution above succeeds with that.Holger Knublauchhttp://www.blogger.com/profile/13180242480924209321noreply@blogger.com0tag:blogger.com,1999:blog-31416365.post-68344814871434964202013-06-12T21:07:00.001-07:002013-06-12T21:07:15.873-07:00Tutorial: Customizing SWA Forms<a href="http://uispin.org/">SPARQL Web Pages</a> (SWP) is a declarative language that represents user interface elements with an RDF vocabulary. It is tightly integrated into TopBraid Suite: TopBraid Composer is used for editing and the TopBraid Live server executes them for web applications. Its textual notation is an extension of HTML, with additional tags to represent certain reusable building blocks.<br />
<br />
The <a href="http://composing-the-semantic-web.blogspot.com.au/2012/07/swp-application-component-library-swa.html">SWP Application Component Library</a> (SWA) includes reusable building blocks that make it easy to configure forms. The resulting components are either used in solutions such as <a href="http://www.topquadrant.com/solutions/ent_vocab_net.html">TopBraid EVN</a>, or can be <a href="http://composing-the-semantic-web.blogspot.com.au/2013/06/embedding-swp-components-into-web-pages.html">embedded into any other web page</a>. Now that SWA has stabilized, I thought it was a good time to explain in-depth how such forms can be used by application builders. For that purpose, I have added a new<br />
<br />
<div style="text-align: center;">
<a href="http://uispin.org/swa-forms.html"><b>Tutorial on SWA Forms</b></a></div>
<br />
that explains how to get from a generic form as the one below<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXakkALyQTzI0lYuhwp82aXY4IIRW4SGA0R8_cHRTyfljI7EfCSVIzMvfbPMSzkAP_tcBEMOAh1qnt6QpUXa8oUZEWeHg5nwWf5Ck1dON5pbV2568XWC1S0LBK0kP0SrXzUUghuw/s1600/swa-Forms-raw.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXakkALyQTzI0lYuhwp82aXY4IIRW4SGA0R8_cHRTyfljI7EfCSVIzMvfbPMSzkAP_tcBEMOAh1qnt6QpUXa8oUZEWeHg5nwWf5Ck1dON5pbV2568XWC1S0LBK0kP0SrXzUUghuw/s400/swa-Forms-raw.png" width="298" /></a></div>
<br />
to a customized layout such as this: <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6AFkscx89U7p_6HTTK01agvyqY1YJQ218KXn5Ct2U0zGgSb4Fuk7N01Q9xAsIIow2OMN5_OXLFhMU4CMUjH_Nw18HRy-c5EeTydqhH88XjnU8hDcKGN9_hbATF9JkZHMWMMnrWQ/s1600/swa-Forms-ObjectsPlaceholder.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6AFkscx89U7p_6HTTK01agvyqY1YJQ218KXn5Ct2U0zGgSb4Fuk7N01Q9xAsIIow2OMN5_OXLFhMU4CMUjH_Nw18HRy-c5EeTydqhH88XjnU8hDcKGN9_hbATF9JkZHMWMMnrWQ/s400/swa-Forms-ObjectsPlaceholder.png" width="351" /></a></div>
<br />
via a small SWP snippet that is attached to a class: <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGwyz5118ePJoaqaJNkTHxEwb9SEV_bmni2pclYfnqwAYZt6sgLZyVXK7NHRSMI4bpdmPGP2qZlzwWeYdxKh-4UrnbdQSVWsUptjUP3NbzyaZl7ykCONdr6rZW7DGGgrTOAYfvmQ/s1600/swa-Forms-result.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="236" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGwyz5118ePJoaqaJNkTHxEwb9SEV_bmni2pclYfnqwAYZt6sgLZyVXK7NHRSMI4bpdmPGP2qZlzwWeYdxKh-4UrnbdQSVWsUptjUP3NbzyaZl7ykCONdr6rZW7DGGgrTOAYfvmQ/s400/swa-Forms-result.png" width="400" /></a></div>
I would like to point out that the source code above is indeed just a visual representation of an RDF-based model, and that ontology can also be queried (with SPARQL) for other purposes. In a sense this SWA vocabulary can fulfill a similar role as earlier attempts such as <a href="http://www.w3.org/2005/04/fresnel-info/">Fresnel</a>, only that SWP is backed by an executable and highly flexible model.Holger Knublauchhttp://www.blogger.com/profile/13180242480924209321noreply@blogger.com0tag:blogger.com,1999:blog-31416365.post-2195846148212801122013-06-11T22:30:00.001-07:002013-06-11T22:59:32.326-07:00Embedding SWP Components into Web Pages with jQuery<a href="http://www.topquadrant.com/swp/">SPARQL Web Pages</a> is a powerful framework for defining HTML renderings of RDF data. Recent releases of TopBraid have added significant improvements to this framework, including a growing library of out-of-the-box components for recurring tasks: the <a href="http://composing-the-semantic-web.blogspot.com.au/2012/07/swp-application-component-library-swa.html">SWA Gadgets</a>. SWA includes components to display or edit details of a given resource, render hierarchies in trees, display a list of instances, provide a search form with various result viewers, faceted search etc. At TopQuadrant we are using these components in our own solutions, including EVN and customer projects. We are committed to keeping these components stable and alive and will continue to improve them.<br />
<br />
So TopBraid customers do not need to reinvent the wheel.<br />
<br />
In order to reuse these components, you do not need to develop your whole application with SWP. Instead you can pick your favorite framework including those based on PHP or modern JavaScript libraries, for the surrounding page. Simply use the SWP components where they make sense. For example, you may need a SKOS Concept tree to drive the navigation of your application - embed an swa:TreeGadget. Or you may want to expose semantic search over your content - embed an swa:FormSearchGadget. Here is a screenshot of "normal" HTML page that includes SWA gadgets loaded from a TopBraid Live server:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGiXJnIjkYkIUkz-sd71UhYAlu5liCA8hsUsBIBRFtwAhF5D1dQ89hInU_Ig0BREPAAT1ExnDWXv8-QpG36uAJDFQXhcmG4U28ekHqCttzl7t_GqgLaknp6xdRn6V8ajCnY8duog/s1600/Embedded-SWA.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="235" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGiXJnIjkYkIUkz-sd71UhYAlu5liCA8hsUsBIBRFtwAhF5D1dQ89hInU_Ig0BREPAAT1ExnDWXv8-QpG36uAJDFQXhcmG4U28ekHqCttzl7t_GqgLaknp6xdRn6V8ajCnY8duog/s400/Embedded-SWA.png" width="400" /></a></div>
You can try this out yourself if you start TopBraid Composer ME 4.3 and go to the URL in the browser above. Let's look at the source code of how this is done.<br />
<ol>
<li>You need to add a few imports to JavaScript and CSS files for jQuery and SWA. Place them in the head of your HTML document.</li>
<li>Create a small script that tells SWA about the location of the SWP servlet and the default RDF graph.</li>
<li>Insert a placeholder div element in the body of your document.
</li>
<li>Write a line of JavaScript that uses jQuery.load (or a similar Ajax call) to replace the div with an HTML snippet from the server.
</li>
</ol>
This is only using mainstream technology that should be familar to most web developers. The interesting bit is how these gadgets interact with each other and how they communicate with the surrounding web page. We use the <a href="http://www.openajax.org/member/wiki/OpenAjax_Hub_2.0_Specification">OpenAjax Event Hub</a> for that (which is also used by the OpenSocial standard). Gadgets publish certain events and any other JavaScript elements can subscribe to those events. For example the following code displays an alert box whenever the selected resource in an swa:Tree changes:<br />
<br />
// Subscribe to class selection event to print selected URI<br />
gadgets.Hub.subscribe("org.example.resourceSelected",<br />
function(event, data) {<br />
alert("Selected resource: " + data);<br />
}<br />
);<br />
<br />
Similarly, your own JavaScript code can publish events to update SWA gadgets, assuming they use the same event name and data payload.<br />
<br />
Please take a look at the source code of the example above - in TopBraid Composer 4.3 it is found in TopBraid/SWA/doc/swadoc.www/embeddedSWADemo.html - and do not hesitate to ask questions and provide feature requests on our mailing list.Holger Knublauchhttp://www.blogger.com/profile/13180242480924209321noreply@blogger.com0tag:blogger.com,1999:blog-31416365.post-84121230226165018182013-06-10T20:30:00.001-07:002013-06-10T20:30:47.747-07:00Faceted Search in TopBraid 4.3Faceted search is a user interface metaphor that is best suitable for explorative scenarios: A user starts by roughly selecting a type of objects and the user interface presents characteristics (or "facets") of the available instances, allowing the user to drill down into specific property values. A faceted search engine displays the available values and the number of matching instances at each step, making it easy to explore the space of available instances without knowing the search keywords in advance.<br />
<br />
An experimental "unpolished" faceted search component had been part of TopBraid for a while, but it had scalability issues and did not integrate well with the rest of the platform. For TopBraid 4.3, we have made a complete redesign to address those issues. A screenshot of the new faceted search capabilities is shown below (click on the image for a larger view):<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZLvf18JLWsOnpHVSp1YAlGX8u74Ur3cTSH0rMvwozNGXE-owujrioCEmP9fp6II0SOi80FyZ-EUU6f4F84monT9IHrmqeJf_1m5qdxBh9NBtmXJsPeC3Sfui7OIrxgIxjyjuoQw/s1600/FacetedSearch-Kennedys.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="186" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZLvf18JLWsOnpHVSp1YAlGX8u74Ur3cTSH0rMvwozNGXE-owujrioCEmP9fp6II0SOi80FyZ-EUU6f4F84monT9IHrmqeJf_1m5qdxBh9NBtmXJsPeC3Sfui7OIrxgIxjyjuoQw/s400/FacetedSearch-Kennedys.jpg" width="400" /> </a></div>
<div class="separator" style="clear: both; text-align: left;">
To get to that screen, open kennedys.ttl in TopBraid Composer ME 4.3, then select the Person class and move to the Browser tab. In the drop down box above the browser, select "facetsapp:Application" and click "Open current page in external Browser". The same can of course be done for any other ontology or class.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The faceted search feature has been implemented in HTML 5/jQuery as <a href="http://composing-the-semantic-web.blogspot.com.au/2012/07/swp-application-component-library-swa.html">SWA</a> gadgets. The component consisting of a search box and the "Limit your search" area is one gadget, and the "summary" view in the center of the screenshot above is another gadget. The search gadget can also be combined with other display gadgets such as the tabular grid views or even a Google Maps view. All views can be customized with a few SWP declarations, e.g. to have certain properties pre-selected as facet fields, and to modify how results are displayed (ask our mailing list if the documentation doesn't help).</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
While it is possible to embed faceted search into any SWP application or HTML 5 web page, TopBraid EVN now also uses faceted search to help selecting objects. The EVN edit forms have a drop down menu that allows users to open up a faceted search dialog. Another way of opening this dialog is from the context menu under the Search gadget in the new <a href="http://composing-the-semantic-web.blogspot.com.au/2013/06/the-topbraid-evn-ontology-editor.html">EVN Ontology Editor</a>.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3XHoXFrqRmuSiBvI0Sv0WmHZ4ez2-MzkC9YCTwt7exJfXBBGKZxjX4hWA40d5fwJz2JEdb0RNKwcZXs4oJ5pETmIaFb6E28bDovRo8VD8u3fTHAIZxkH1F6dwCUiQ1v23plvzcA/s1600/FacetedSearch-NPD-Fields.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3XHoXFrqRmuSiBvI0Sv0WmHZ4ez2-MzkC9YCTwt7exJfXBBGKZxjX4hWA40d5fwJz2JEdb0RNKwcZXs4oJ5pETmIaFb6E28bDovRo8VD8u3fTHAIZxkH1F6dwCUiQ1v23plvzcA/s400/FacetedSearch-NPD-Fields.jpg" width="400" /></a></div>
In addition to the facets and count display, more specific results can be obtained through a free-text search box in the upper left corner:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7VWyaERPzi1K5ZvIQ5T-pHI3E8LVgnPSJPCRNZ42wdpBsXWBJ1SN7YzetxtosArFk7oVxZ2rHNaf4eKx1QZISxOhrg4SuzboJg9xQ0L23HxzPAZhnv-Vgo6JaB0_nu3vd41D5sA/s1600/FacetedSearch-NPD-Fields2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7VWyaERPzi1K5ZvIQ5T-pHI3E8LVgnPSJPCRNZ42wdpBsXWBJ1SN7YzetxtosArFk7oVxZ2rHNaf4eKx1QZISxOhrg4SuzboJg9xQ0L23HxzPAZhnv-Vgo6JaB0_nu3vd41D5sA/s400/FacetedSearch-NPD-Fields2.jpg" width="400" /></a></div>
The faceted search components can seamlessly operate in two different modes. By default, it will use a native SPARQL-based engine that will work directly on the RDF store. This is fine for small to medium-sized data sets, but may become slow when too many counts need to be computed. The alternative mode is using <a href="http://lucene.apache.org/solr/">Apache Solr</a>, a Lucene-based search index that is optimized for faceted search scenarios. To make use of this, you only need to configure your TopBraid EVN project to synchronize with a Solr server. TopBraid will automatically update the Solr index after each edit (to the master graph) and then automatically use Solr to do the heavy lifting of computing the facet counts. The structure of the ontology is still used to discover which properties are present, and for the detailed displays if someone clicks on an instance. This hybrid approach combines the power of ontologies with an the optimized native data structure provided by Solr.<br />
<br />
The flexibility of the RDF data model is well suited to serve as foundation for faceted search scenarios. The TopBraid platform provides a highly optimized yet flexible platform for delivering faceted search to your end users. No programming is needed to get started - this is model-driven throughout.Holger Knublauchhttp://www.blogger.com/profile/13180242480924209321noreply@blogger.com0tag:blogger.com,1999:blog-31416365.post-15355060804598936472013-06-10T03:42:00.000-07:002013-06-10T03:42:45.937-07:00The TopBraid EVN Ontology EditorThe evolution of the <a href="http://www.topquadrant.com/solutions/ent_vocab_net.html">TopBraid Enterprise Vocabulary Net (EVN)</a> has reached a new milestone with release 4.3. While EVN is long established as a leading web editor for SKOS-based Thesauri and controlled vocabularies, we have generalized the product so that it can also be used to edit arbitrary other RDF Schema or OWL models. The new Ontology Editor inherits most of the features of the EVN SKOS vocabulary editor, including the change tracking infrastructure and the familiar UI components. Here is a screenshot of the Ontology Editor in EVN 4.3 (click on an image for a larger view):<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisYgPL4xT0SGoWNaV27YyDXAuS-NxcZVSizQ8E9-_jIvOz93oTMqiZjOsgtEEtT-GWqtF9oDhOOZJagAJz-P4bZecowfdHPbQgtA0S6B2NDxevR6qvMvdANqAo1UKu_HYdIKmSsQ/s1600/EVN-Ontology-View-Arnold.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="185" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisYgPL4xT0SGoWNaV27YyDXAuS-NxcZVSizQ8E9-_jIvOz93oTMqiZjOsgtEEtT-GWqtF9oDhOOZJagAJz-P4bZecowfdHPbQgtA0S6B2NDxevR6qvMvdANqAo1UKu_HYdIKmSsQ/s400/EVN-Ontology-View-Arnold.jpg" width="400" /></a></div>
<br />
We have placed a mixed class-property-tree on the left, with buttons to create new classes and datatype or object properties. Under the tree, a tabular view allows users to select instances or create new ones. Auto-complete fields under the tree and instances areas support quick navigation. A powerful search form is placed on the right, with features that allow the construction of even complex queries with nested objects, regular expressions, range queries and other patterns. Search results can be used to navigate around but can also be exported to spreadsheets - columns can be selected with the provided checkboxes.<br />
<br />
Details of the selected resource are displayed in the center area, which can be toggled between view and edit mode. As shown below, the edit forms have a new feature that makes it possible to edit "depending" objects such as the Address of a Person using nested sub-forms (the resulting objects are represented as blank nodes).<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDQNlnTKbaB9fQXdejdyC086mKewghAeVZVP_D4PUWLY5ODg4JU7i2X5G_2QGw-V57UWSFjyLpwcr4MOzirYTasUmty9wN0EXkCrTE66ZPRMM6RZPSSgx0aqo3_7dg7j3rFKxBPA/s1600/EVN-Ontology-Edit-Holger.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="293" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDQNlnTKbaB9fQXdejdyC086mKewghAeVZVP_D4PUWLY5ODg4JU7i2X5G_2QGw-V57UWSFjyLpwcr4MOzirYTasUmty9wN0EXkCrTE66ZPRMM6RZPSSgx0aqo3_7dg7j3rFKxBPA/s400/EVN-Ontology-Edit-Holger.jpg" width="400" /></a></div>
<br />
EVN is a complete solution for editing classes, properties and instances. For classes, we have integrated a constraint editor based on <a href="http://composing-the-semantic-web.blogspot.com.au/2009/01/understanding-spin-templates.html">SPIN templates</a>. As shown below, average users do not need to understand how constraints are implemented - they only need to fill in the blanks on a form. Several constraint types are delivered out of the box, but almost arbitrary constraints can be added by users who are familiar with SPARQL.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVPsjIUXB-kUMpShoiia_eZ56TyrOoBhD__BwRkCG4cpf76oZQ-O_XG2Hfk8lf-ybRRJCAXxxFFWALtiwiYge_07WL0DdYvGshkjmVkfP4ues7fbvszXyVNwZleNEV35quxjvo6w/s1600/EVN-Ontology-Constraint-Editor.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="133" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVPsjIUXB-kUMpShoiia_eZ56TyrOoBhD__BwRkCG4cpf76oZQ-O_XG2Hfk8lf-ybRRJCAXxxFFWALtiwiYge_07WL0DdYvGshkjmVkfP4ues7fbvszXyVNwZleNEV35quxjvo6w/s400/EVN-Ontology-Constraint-Editor.jpg" width="400" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
EVN has a sophisticated infrastructure for change tracking. Every ontology has its own life cycle and user permissions. The manager of an ontology can assign roles to other users, allowing them to either edit the "master" copy directly, or to create so-called "working copies" based on master. A working copy is a branch that may contain changes that need to be reviewed before they can be merged into master. EVN provides various elements for reviewing changes. As shown below, the forms can be switched into a history mode in which added and deleted statements are highlighted:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFOssNNmaneeT3311DR6OYRf4HBTe52gkgzhzlaIZuKjdD9JkmKji4ViDrroqSdlIelO5AUC7sXhWRvra5LjY38tmEmZQHM9FHFtrl8KNCgW9BJicfAlqy2qSz0WBs5Rf6mOWRiw/s1600/EVN-Ontology-Inline-History.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="371" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFOssNNmaneeT3311DR6OYRf4HBTe52gkgzhzlaIZuKjdD9JkmKji4ViDrroqSdlIelO5AUC7sXhWRvra5LjY38tmEmZQHM9FHFtrl8KNCgW9BJicfAlqy2qSz0WBs5Rf6mOWRiw/s400/EVN-Ontology-Inline-History.jpg" width="400" /></a></div>
Every change in EVN is tracked in a dedicated model - we love to use RDF all the way down, so the change history itself is represented in RDF and can therefore be queried uniformly via SPARQL. The Change History view allows users to browse and search the complete change history as shown below.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYQvRY-NoRE39CRIf-rLjpIW8zkULIP_qUIhXL4VSxCvnNlC2-I26rHUgnZn2_om28skugPau5wALIGZLoXfExQNxr5V47dnERZVnHw5kG0Qdt8N8aLuRfc0kDKE75iAwXHGeDdg/s1600/EVN-Ontology-ChangeHistory.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="195" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYQvRY-NoRE39CRIf-rLjpIW8zkULIP_qUIhXL4VSxCvnNlC2-I26rHUgnZn2_om28skugPau5wALIGZLoXfExQNxr5V47dnERZVnHw5kG0Qdt8N8aLuRfc0kDKE75iAwXHGeDdg/s400/EVN-Ontology-ChangeHistory.jpg" width="400" /></a></div>
<br />
The EVN user interface is able to operate meaningfully on almost every ontology because it uses the ontology's structure to discover which properties make sense in which context, and how they should be displayed. However, in some cases a generic display of properties is not the best way to render information. Therefore, one of the strengths of EVN is its customizability. EVN is built using <a href="http://www.topquadrant.com/swp/swp-in-topbraid.html">SPARQL Web Pages</a>, and in particular the <a href="http://composing-the-semantic-web.blogspot.com.au/2012/07/swp-application-component-library-swa.html">SWA component library</a>. I should write many more blog entries on the various customization techniques, but for now let me enumerate a few.<br />
<ul>
<li>EVN used standard HTML 5 and jQuery, and well-defined CSS styles can be overloaded to change look and feel. </li>
<li>The layout of forms can be customized (by attaching a different ui:instanceView to a class)</li>
<li>Custom widgets can be installed to display, edit or search certain values (via subclasses of swa:Widget)</li>
<li>It is possible to add new actions for the drop down menus and those actions may execute arbitrary JavaScript code or call servlets that read or update data.</li>
<li>The whole layout of the application can be changed, for example to add new views. The platform underlying EVN has been generalized and its gadgets can be plugged together in different ways.</li>
</ul>
If you want to experiment with EVN, just <a href="http://www.topquadrant.com/products/TB_download.html">download</a> TopBraid Composer Maestro Edition and get started - TopBraid Composer launches a built-in web server that makes it possible for you to interact with ontologies from a web browser. We are looking forward to your feedback on the first 4.3 beta release.Holger Knublauchhttp://www.blogger.com/profile/13180242480924209321noreply@blogger.com0tag:blogger.com,1999:blog-31416365.post-35640041316036658432013-05-05T17:41:00.000-07:002013-05-06T15:14:41.859-07:00Example: Converting the Kennedys Ontology to schema.org with SPINMapWith <a href="http://schema.org/">schema.org</a>'s <a href="http://www.w3.org/wiki/WebSchemas">growing popularity</a>, I thought it was a good idea to validate and illustrate how it can be used as a shared base ontology for various use cases. At <a href="http://topquadrant.com/">TopQuadrant</a> we have been using a <a href="http://topbraid.org/examples/kennedys">Kennedys Ontology</a> in training and example material for many years. It consists of instances of a class kennedys:Person with various properties ranging from names to educational background and family relationships. Looking at <a href="http://schema.org/Person">schema.org/Person</a> we can see property definitions for very similar, if not identical, things.<br />
<br />
Here is how to convert the kennedys ontology into schema.org with <a href="http://www.topquadrant.com/products/TB_Composer.html">TopBraid Composer</a> and SPINMap. <a href="http://composing-the-semantic-web.blogspot.com.au/2011/04/spinmap-sparql-based-ontology-mapping.html">SPINMap</a> is a powerful rule-based transformation language with a graphical notation that can be used to create target RDF triples from a collection of source instances. As the first step, we create an empty RDF file called schemakennedys that imports schema.org. Then we create a new SPIN file that imports schemakennedys and the SPINMap namespace:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglUjM2-duyR3qKj8trPd9nLXm-1mM3fzoQYmdNotprbqaThK78SI1jclK3ybSMP8EwcLtBRfDeVLagmG6xuFQ3fOfpCp1gzDMBj1gvQTm78SXRdNZF4zD0uJjhk4s0SifeOxUINA/s1600/Kennedys2schema-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="392" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglUjM2-duyR3qKj8trPd9nLXm-1mM3fzoQYmdNotprbqaThK78SI1jclK3ybSMP8EwcLtBRfDeVLagmG6xuFQ3fOfpCp1gzDMBj1gvQTm78SXRdNZF4zD0uJjhk4s0SifeOxUINA/s400/Kennedys2schema-1.png" width="400" /></a></div>
<br />
Using drag-and-drop, we can add the imports of schemakennedys (the target file) and kennedys (the source file) into that SPINMap file:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJif5QLNBM7OsKjkXNjfnXDXEVS9txvFEYmIB3FUl7J-i4cqrR8G2JCyNst0-f_SL-TWuGuhyphenhyphen970170bZu9FSgFhL_e0DmmWRYTVDwF0L2n1ZWgtBZ5rswG0Wmfa-VNiYggbpBog/s1600/Kennedys2schema-2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="99" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJif5QLNBM7OsKjkXNjfnXDXEVS9txvFEYmIB3FUl7J-i4cqrR8G2JCyNst0-f_SL-TWuGuhyphenhyphen970170bZu9FSgFhL_e0DmmWRYTVDwF0L2n1ZWgtBZ5rswG0Wmfa-VNiYggbpBog/s400/Kennedys2schema-2.png" width="400" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
Now we need to select the source class of our mapping with a double-click on kennedys:Person. We switch to the Diagram tab of that class and drag the target class schema:Person from the class tree onto the Diagram area. Now we establish a link from the top of the kennedys:Person box to the top of the schema:Person box. We have various options there to convert URIs but since we want to reuse the same URIs, we simply use spinmapl:self as the transformation context function. Now we can use drag and drop to establish links from the properties on the left to the properties on the right:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh46-GkDDbhuNu3WoXittm_n5b8Z21Gbj_gJO3ipszzGW3ZeZZMUe50Ams290Sp3-zbxSo7g60ZqPHXBCkUIOTH0j7a7x7JSlo20L6QgzkbRUZ3n5oALy6KYEzEyieNfpOYu1TgNg/s1600/Kennedys2schema-3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="175" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh46-GkDDbhuNu3WoXittm_n5b8Z21Gbj_gJO3ipszzGW3ZeZZMUe50Ams290Sp3-zbxSo7g60ZqPHXBCkUIOTH0j7a7x7JSlo20L6QgzkbRUZ3n5oALy6KYEzEyieNfpOYu1TgNg/s400/Kennedys2schema-3.png" width="400" /></a></div>
<br />
Most mappings are straight-forward one-to-one mappings because the properties such as spouse and parent are almost identical. The only "interesting" cases are kennedys:gender and kennedys:profession, which are objects in the left model but simple string properties in the right one. In order to convert the objects to strings, we can use any SPARQL or SPIN function, and here the function spif:name is doing exactly what we need. The properties kennedys:deathYear and kennedys:birthYear cannot be mapped to schema:birthDate and schema:deathDate because they do not contain enough information for month and day. We do not map kennedys:child because it can be derived from schema:parent and it would be unnecessary to have the same information stored twice.<br />
<br />
Then we create a similar SPINMap for kennedys:College:<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLEjjCHYW7RZ-Zi21k3MTLNT6M7TgFaFeNEqLuVnqtKqgLuDKyU9MnetpyVLeufBEgs3EqXAJFDeRjA-ZwdHCYvR17A76sRaL1paCuMQe192N4ApX0XRHDKOnZTX50oIRI8Wik6g/s1600/Kennedys2schema-3b.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="141" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLEjjCHYW7RZ-Zi21k3MTLNT6M7TgFaFeNEqLuVnqtKqgLuDKyU9MnetpyVLeufBEgs3EqXAJFDeRjA-ZwdHCYvR17A76sRaL1paCuMQe192N4ApX0XRHDKOnZTX50oIRI8Wik6g/s400/Kennedys2schema-3b.png" width="400" /></a></div>
<br />
The mapping above is very simple because the original kennedys ontology does not contain much information about colleges. Now we can trigger the execution of the rules with a single click on the Run Inferences button. This will create new RDF triples that can be explored in various ways, including the Inferences View as shown below:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAU9GfgTax06KceyIhNqTm65EwVYBuNveFivOEnAniHcSh-keB5jDk64U3t4tQj3MJe2Y7QuAuFWr1l7TdQi19MCw3JkWQeqOpsH4txCwJOOHnsdRULaAUCyplU8-72B7T_b7HaA/s1600/Kennedys2schema-4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="98" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAU9GfgTax06KceyIhNqTm65EwVYBuNveFivOEnAniHcSh-keB5jDk64U3t4tQj3MJe2Y7QuAuFWr1l7TdQi19MCw3JkWQeqOpsH4txCwJOOHnsdRULaAUCyplU8-72B7T_b7HaA/s400/Kennedys2schema-4.png" width="400" /></a></div>
<br />
The context menu of the Inferences View has a menu item "Assert all to graph..." in which we select the schemakennedys target graph. The content of this file is now the set of schema:Person instances with exactly the same family relationships like the original ontology:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinYFO0SL-buQ4o6-bXuQpfX-NLPAJcaAP9KdaMNBwTgS7JvIn6NPUmmq3ulO4tmHmI_3HyqvEPxmm6gxyBnlf4QboisPnMOT5B5ixwMAMthIi7GRkX2hLz6v1nHylYNxFeWtPCEw/s1600/Kennedys2schema-5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="352" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinYFO0SL-buQ4o6-bXuQpfX-NLPAJcaAP9KdaMNBwTgS7JvIn6NPUmmq3ulO4tmHmI_3HyqvEPxmm6gxyBnlf4QboisPnMOT5B5ixwMAMthIi7GRkX2hLz6v1nHylYNxFeWtPCEw/s400/Kennedys2schema-5.png" width="400" /></a></div>
<br />
The resulting ontology is now present at <a href="http://topbraid.org/examples/schemakennedys">http://topbraid.org/examples/schemakennedys</a>Holger Knublauchhttp://www.blogger.com/profile/13180242480924209321noreply@blogger.com0tag:blogger.com,1999:blog-31416365.post-30752776644032658742013-01-30T16:54:00.000-08:002013-01-30T16:54:31.723-08:00SPIN Syntax Simplified<a href="http://spinrdf.org/">SPIN</a> (<a href="http://www.w3.org/Submission/2011/SUBM-spin-overview-20110222/">W3C member submission</a>) is an RDF vocabulary to embed SPARQL-based rules, constraints, functions and templates into semantic web models. It also includes a <a href="http://spinrdf.org/sp.html">triple-based serialization</a> of SPARQL which can be used to share the SPARQL queries of rules, constraints etc in a machine-friendly format. Among others, this syntax operates on true URI references and is therefore independent of prefix declarations, makes it easier to find and refactor the resources used in the query and supports various meta-operations on the structure of a query.<br />
<br />
However, over the years I have collected overwhelming feedback that the SPIN RDF notation is an obstacle to wider adoption of SPIN. I have therefore made the SPIN syntax more flexible, so that SPIN files can more easily be edited in text files, and to reduce the implementation costs of SPIN engines. The change that I have made to the spec (which is now <a href="http://spinrdf.org/spin.html">online</a>) is very small: SPIN already had a property called <span style="font-family: "Courier New",Courier,monospace;">sp:text</span> that can be used to store a query string in the conventional textual representation of SPARQL. All I needed to change was that:<br />
<br />
<div style="text-align: center;">
<b>If <span style="font-family: "Courier New",Courier,monospace;">sp:text</span> is present, then the SPIN RDF triples are optional.</b></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
With this change, a SPIN rule can be edited in Turtle as:</div>
<div style="text-align: left;">
<br /></div>
<pre class="query">ex:Person
a rdfs:Class ;
rdfs:label "Person"^^xsd:string ;
rdfs:subClassOf owl:Thing ;
spin:rule
[ a sp:Construct ;
sp:text """
CONSTRUCT {
?this ex:grandParent ?grandParent .
}
WHERE {
?parent ex:child ?this .
?grandParent ex:child ?parent .
}"""
] .</pre>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
and a SPIN constraint based on an ASK becomes:</div>
<div style="text-align: left;">
<br /></div>
<pre class="query">ex:Parent
a rdfs:Class ;
rdfs:label "Parent"^^xsd:string ;
rdfs:subClassOf ex:Person ;
spin:constraint
[ a sp:Ask ;
sp:text """
# must be at least 18 years old
ASK WHERE {
?this ex:age ?age .
FILTER (?age < 18) .
}"""
] .</pre>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
I believe this change supports the best of both worlds: editing tools such as TopBraid Composer can use the RDF syntax to keep track of references and support automated refactorings, while published models may only include the <span style="font-family: "Courier New",Courier,monospace;">sp:text</span> triples (or both) to make it easier for 3rd party tools to use the SPIN definitions. The implementation burden of this change is very light - all I needed to change in the SPIN API was a single method that turns the sp:Constructs etc into Jena Query objects. The only downside of this change is that there may be two dialects appearing and that some implementations may not support the full RDF syntax. If the market adopts these changes, then 3rd party vendors will probably only support the text syntax, so that most published models may end up containing the <span style="font-family: "Courier New",Courier,monospace;">sp:text</span> triples.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
The next version of TopBraid (4.2) will have one-click features to move between the two syntaxes, for example to switch to the text syntax before publishing a SPIN file. A new version of the SPIN API will be available shortly.</div>
Holger Knublauchhttp://www.blogger.com/profile/13180242480924209321noreply@blogger.com0tag:blogger.com,1999:blog-31416365.post-88389740285284529812012-07-02T18:09:00.002-07:002012-07-02T18:09:45.016-07:00The SWP Application Component Library (SWA)<p>There are many different technologies for building HTML user interfaces based on semantic web models. TopQuadrant's <a href="http://uispin.org">SPARQL Web Pages (SWP)</a> is aimed at a maximum of integration between RDF/OWL models and their visual representation. Not only can RDF resources and classes be linked to their most suitable renderings, but even the visual components themselves can be shared as linked data, taking the vision of model-driven development to the next stage. SWP is Linked Data taken to extremes.</p>
<p>SWP makes it easy to encapsulate HTML snippets into reusable components. The resulting components can be embedded into other HTML snippets as new XML/HTML tags. This makes it easier for web or RDF developers to reuse work prepared by others. Instead of reinventing the wheel, groups of developers across the web can share the same URIs for reusable components, and linked data principles can be used to discover and integrate them. Instead of hard-coding an application's behavior, this mechanism supports a new generation of web front ends that have a small, generic core architecture that is ready to work with any type of data, while specific types of behavior are brought in from web ontologies and their associated SWP triples.</p>
<p>The SWP Application Component Library (SWA) is the result of our (ongoing) work on defining a set of reusable components that lower the bar for developers who want to build user interfaces that are driven by semantic web models. It contains easy to use elements for building rich Ajax-based components including forms, trees, grids and more. The goal of this blog entry is to encourage you to take a look at the documentation of SWA which is built into TopBraid Composer ME 3.6.1 (or above) and accessible from the menu <b>Help > SWA Help/Examples</b>. Alternatively, start TBC-ME, open a browser and navigate to <a href="http://localhost:8083/tbl/swp?_viewClass=swadoc:Index">http://localhost:8083/tbl/swp?_viewClass=swadoc:Index</a>. The help page of SWA is written in SWP itself and contains fully operational examples. Some highlights of these examples are illustrated below.</p>
<p>Starting with a simple example that shows a tree alongside a form, you can see how easy it is to use the SWA components.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWKxMfPc5I0IIjOkj5D0Xo_PFE3mU4iU2g4jkyQGahUHfA2xEtTROUJ7oDYvR7MR8u5ZdXzpqp8-7E6f56IBxaqLWYlMaBWrSK2y2g9psoMdIQNpNp7FD4i_rvDNo7W_puJzXFvQ/s1600/SWA-Example.png" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="231" width="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWKxMfPc5I0IIjOkj5D0Xo_PFE3mU4iU2g4jkyQGahUHfA2xEtTROUJ7oDYvR7MR8u5ZdXzpqp8-7E6f56IBxaqLWYlMaBWrSK2y2g9psoMdIQNpNp7FD4i_rvDNo7W_puJzXFvQ/s400/SWA-Example.png" /></a></div>
<p>If you need a tree, just insert a <code><swa:Tree></code> element. If you need to react on a click on a tree node, use <code>arg:onSelect="(javascript)"</code>. Dynamic behavior can be achieved by reloading a section of your page, such as the form above. The whole library is based on jQuery and its UI widgets, but provides a convenience layer around it that makes interaction with RDF through SPARQL quite easy.</p>
<p>The next example shows how form layouts can be defined. There are default forms for all resources but these basically list all properties from top to bottom. If you want to customize this, you can use the <code><swa:Objects></code> tag. All you need to specify is the property that you want to be displayed:</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUESdel7wAaxcJA1PRbMd0ReHZuTX4u01lHZfYjhijmn5kemiLqvAcjMP3q0kR0DLzw_ATqt__7pZC5Q4I60jnLyOAstNWKEWqpudjDH3GnROZuv1lfhAE32CK7OiMdecQW58vDA/s1600/SWA-Objects.png" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="240" width="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUESdel7wAaxcJA1PRbMd0ReHZuTX4u01lHZfYjhijmn5kemiLqvAcjMP3q0kR0DLzw_ATqt__7pZC5Q4I60jnLyOAstNWKEWqpudjDH3GnROZuv1lfhAE32CK7OiMdecQW58vDA/s400/SWA-Objects.png" /></a></div>
<p>A feature of SWA forms is that they can be used in different modes: in <b>View mode</b>, the UI will select pure display widgets such as labels and images. In <b>Search mode</b> the form will provide input fields for value ranges etc. In <b>Edit mode</b> the form will consist of editing elements such as text boxes and date widgets. All of those widgets are selected in a completely model-driven way based on information from the RDF models. This also makes it possible to define custom widgets for data and object types from your specific application or domain.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2-wqzB-5qQhByIqss9j6I7hmu-j5Y4TwBjHegBTKrQIudxnj5G7YXi46oyVZNA2sU7J71YQ_rt5boozZfRK20ZLkSPm9T8N3M69cEYc2-7xYW-K20428uCxuw2nwHW8c8pQESPg/s1600/SWA-Forms.png" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="189" width="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2-wqzB-5qQhByIqss9j6I7hmu-j5Y4TwBjHegBTKrQIudxnj5G7YXi46oyVZNA2sU7J71YQ_rt5boozZfRK20ZLkSPm9T8N3M69cEYc2-7xYW-K20428uCxuw2nwHW8c8pQESPg/s400/SWA-Forms.png" /></a></div>
<p>The Search form can easily be linked up with a table/grid viewer that displays the matching resources.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8xWwlo8clEGVfhIXIZCDC9IQ2xpXFRwoLPOuTtgD09t4Ivtxlq9dbTN1wm_ol-THIge2mq3LJ37C0c4-u2mq5cD3UGXtZ6EpFUuI92tkq-kDPhoTMyy_451ET_UYqPqIG1n8pgw/s1600/SWA-Search.png" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="278" width="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8xWwlo8clEGVfhIXIZCDC9IQ2xpXFRwoLPOuTtgD09t4Ivtxlq9dbTN1wm_ol-THIge2mq3LJ37C0c4-u2mq5cD3UGXtZ6EpFUuI92tkq-kDPhoTMyy_451ET_UYqPqIG1n8pgw/s400/SWA-Search.png" /></a></div>
<p>Another little widget is the <code>swa:AutoComplete</code> component that supports type-ahead data entry driven by the labels of instances of a given class.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjH4RhzN1ytN-j7QEoFXJPZD-YPbstbT7ChnSWHPUfsAtW8ZqKlvYCqY9v6PGhyphenhyphenFNvmAllwyQbCjpaSXSRgSh-Jsv4gmUhQT1F2S3oX3oT1dU7frqGYMjxLnCJLxkpVBK2LD_6GkA/s1600/SWA-AutoComplete.png" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="218" width="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjH4RhzN1ytN-j7QEoFXJPZD-YPbstbT7ChnSWHPUfsAtW8ZqKlvYCqY9v6PGhyphenhyphenFNvmAllwyQbCjpaSXSRgSh-Jsv4gmUhQT1F2S3oX3oT1dU7frqGYMjxLnCJLxkpVBK2LD_6GkA/s400/SWA-AutoComplete.png" /></a></div>
<p>The SWA library is still under active development. Its evolution is currently driven by the upcoming release of <a href="http://www.topquadrant.com/solutions/ent_vocab_net.html">Enterprise Vocabulary Net</a> with a pure HTML-based user interface. However, I believe the interface of most SWA components is sufficiently stable now so that interested users may want to play around with it. At the time of writing this blog entry, editing support is unfinished for the general use outside of EVN, but pure viewer applications for data browsing should work fine. We certainly appreciate feedback.</p>Holger Knublauchhttp://www.blogger.com/profile/13180242480924209321noreply@blogger.com0tag:blogger.com,1999:blog-31416365.post-48522502268148062582012-06-28T18:11:00.000-07:002012-06-28T18:11:01.801-07:00Graphical Ontology Editing with TopBraid Composer's Diagram TabOne of the new features in TopBraid Composer 3.6 is the ability to edit RDFS and OWL ontologies in a graphical notation. In the past, the Diagram Tab had been for viewing only. But judging from the number of screenshots all over the web, the Diagram seems to be quite widely used, so it would be a wasted opportunity to not make it editable too. This enhancement hopefully makes TopBraid Composer more accessible to users with UML modeling experience.<br /><br />
I'll walk through a few simple edit operations. The starting point is the kennedys.ttl ontology found in the TopBraid/Examples folder. I have activated the "Human-readable labels" mode with the corresponding button in the tool bar. I have also selected "Start Hierarchy with owl:Thing" in the context menu of the Classes view. In the preferences of the Diagram, I have deactivated "Show root class".<br /><br />
Select the Person class in the tree and switch to the Diagram tab at the bottom of the form. This automatically renders the Person class and its neighbors.<br /><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKvs-SixuP9yHWY0Hse5ro4_ETmnGK-J1XY6uUOn2c0eM40bIBFiYr0M257pzPZ3zV3zkqrsxnhi2ZF1ZOh5z23QFhlQKPzOjH0I_sgGXAgcV8zRFiAWst12nkoKq5-NLTPkzIeQ/s1600/TBC-Diagram-Editing-1.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="226" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKvs-SixuP9yHWY0Hse5ro4_ETmnGK-J1XY6uUOn2c0eM40bIBFiYr0M257pzPZ3zV3zkqrsxnhi2ZF1ZOh5z23QFhlQKPzOjH0I_sgGXAgcV8zRFiAWst12nkoKq5-NLTPkzIeQ/s400/TBC-Diagram-Editing-1.PNG" width="400" /></a></div>
You can see a palette with edit operations showing up on the left side. Select "Create Class" and click on an empty area of the screen. This opens the following dialog:<br /><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYAbA7njZCP6eW0zCQuLGJI4AjJb9fKYCsWJGcsm1ITIYP8MPNYy06REYVeju3Pjh3NI-T-EX1VwuHbCfAcMt76Qfb4sjpmJq4auvu_Y_pi8HEsDqRphyT-Fp9r8A_XjiUo1bLRA/s1600/TBC-Diagram-Editing-2.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYAbA7njZCP6eW0zCQuLGJI4AjJb9fKYCsWJGcsm1ITIYP8MPNYy06REYVeju3Pjh3NI-T-EX1VwuHbCfAcMt76Qfb4sjpmJq4auvu_Y_pi8HEsDqRphyT-Fp9r8A_XjiUo1bLRA/s400/TBC-Diagram-Editing-2.PNG" width="345" /></a></div>
Enter kennedys:Address as class name and click Ok. A new class box now shows up. Switch to the "Add Association" mode in the palette and drag a connection from Person to Address. This opens a dialog to edit the property name:<br /><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimWmDHd9AfhQqJni-io9VDwKu2yytBiJZNKIxVIW6_Nbum1uAZNlR-NjZXqjV43A0-8B3Y4bFZqyCy5Pf_PpoxKyPeMGzBZuN0HAP5k1UldJQQyTw40fI2MGIYGO0HpOJOB3HBwQ/s1600/TBC-Diagram-Editing-3.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="237" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimWmDHd9AfhQqJni-io9VDwKu2yytBiJZNKIxVIW6_Nbum1uAZNlR-NjZXqjV43A0-8B3Y4bFZqyCy5Pf_PpoxKyPeMGzBZuN0HAP5k1UldJQQyTw40fI2MGIYGO0HpOJOB3HBwQ/s400/TBC-Diagram-Editing-3.PNG" width="400" /></a></div>
Enter kennedys:address (in lower-case because it's a property) and click Ok. When you now move your mouse over the Address class, you can see a button that can be used to add new attributes (datatype properties). Use this to add street, postalCode etc.<br /><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigx5UgAr1_C6930kNDTD9oWNxpAZScTFE51O-DqP7DBwsX9iDQNxQZ9o-4MGsThAZp0YNai1wr5DDEUy9zP_fB8d34IjQ1Ea-trbsqaTrbUiipfkKcgj5bweDy1XDXx3aVPG4NxA/s1600/TBC-Diagram-Editing-4.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigx5UgAr1_C6930kNDTD9oWNxpAZScTFE51O-DqP7DBwsX9iDQNxQZ9o-4MGsThAZp0YNai1wr5DDEUy9zP_fB8d34IjQ1Ea-trbsqaTrbUiipfkKcgj5bweDy1XDXx3aVPG4NxA/s400/TBC-Diagram-Editing-4.PNG" width="400" /></a></div>
For attributes / datatype properties, the following dialog allows you to pick the range of the new property in a single go.<br /><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR_XqSb0RKnHnCfHxsyplMxYOUcFyKd10nI4TGve5Cl47sruxSh6KLvJFsltPYjVf18PTD3Y41res3bCLGNZnVa2x8LUYxsRzQyqP9QVHl8s54P7XOYgwGD0bb_mtmS47OR-hfrg/s1600/TBC-Diagram-Editing-5.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="266" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR_XqSb0RKnHnCfHxsyplMxYOUcFyKd10nI4TGve5Cl47sruxSh6KLvJFsltPYjVf18PTD3Y41res3bCLGNZnVa2x8LUYxsRzQyqP9QVHl8s54P7XOYgwGD0bb_mtmS47OR-hfrg/s400/TBC-Diagram-Editing-5.PNG" width="400" /></a></div>
You can modify ranges, comments etc at any stage later by double-clicking on the attributes or classes. You can also right-click on attributes or associations to easily specify cardinalities based on owl:Restrictions.<br /><br />
Overall I believe this is a straight-forward feature that will hopefully make it easier for people to quickly design ontologies using an intuitive graphical notation.Holger Knublauchhttp://www.blogger.com/profile/13180242480924209321noreply@blogger.com0tag:blogger.com,1999:blog-31416365.post-84831559343432185812012-02-23T16:30:00.012-08:002012-02-23T17:12:58.358-08:00SWP Tip: Organizing Queries and Views<a href="http://uispin.org/">SPARQL Web Pages</a> is a flexible language to build web interfaces based on RDF data. Its flexibility makes it possible to apply different styles of development, depending on the size of the team and whether you are developing a quick demo or a maintainable system. In this post I examine some design patterns that I have found useful to keep my SWP projects well organized.<br /><br />Let's walk through an example based on the infamous Kennedys ontology. You are welcome to follow along with TopBraid Composer 3.5 or above. In this example I am building a view that displays all children of a given Person in HTML:<br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKnaUtgkVLpKuFStQ2LC4xK51ZuaBct-krx14pz0Rt8Nb8RKJAmexTOJL0H2cTymjTsudTiY96PdZFcY34JxqZx0XLYaXa3cUC1kOFDRBb_NE43htCs6NWvWXQbB66BqYl94ctcg/s1600/swp-template-07.PNG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 298px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKnaUtgkVLpKuFStQ2LC4xK51ZuaBct-krx14pz0Rt8Nb8RKJAmexTOJL0H2cTymjTsudTiY96PdZFcY34JxqZx0XLYaXa3cUC1kOFDRBb_NE43htCs6NWvWXQbB66BqYl94ctcg/s400/swp-template-07.PNG" alt="" id="BLOGGER_PHOTO_ID_5712494862434138226" border="0" /></a><br /><br />The quickest way of building such a view is simply by attaching the following ui:instanceView to the Person class:<br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIhvi5tdhS97d3c5UIUcb-zbKAM5Ih7sdV8aWfIvvatjrKyHccvt3DAsOX2O7Du3h7XWf7GALUVObX1q6-YpRS71LEKPWAK9PBo8uwNj6B167dGSN_bANcP2DopNSbnfi735Cd1g/s1600/swp-template-00.PNG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 172px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIhvi5tdhS97d3c5UIUcb-zbKAM5Ih7sdV8aWfIvvatjrKyHccvt3DAsOX2O7Du3h7XWf7GALUVObX1q6-YpRS71LEKPWAK9PBo8uwNj6B167dGSN_bANcP2DopNSbnfi735Cd1g/s400/swp-template-00.PNG" alt="" id="BLOGGER_PHOTO_ID_5712495209700685458" border="0" /></a><br />This approach has a couple of problems. Embedding the query into the document mixes presentation layer with application logic. This does not only make the page harder to read but also prevents division of label within a team of developers. Another problem is that nothing from the snippet above is easily reusable elsewhere. So let's start from scratch and do a clean design.<br /><br />A key technology to separate layout from queries is to employ SPIN templates - named queries that can be stored in a different file and reused in many places. In TBC, we use the New > RDF/OWL/SPIN file wizard to produce a file kennedys.spin.ttl:<br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzRn5ZsZ6LKK2gcAG1RHUHdfG7-LN3ukp1KQArDJgSxnYf6XLehPemJ5RmFgpBYhSge3_zvJzV2KRnG2Csln66RNB2eA-YO_ZawI6EIeo8IVOF-h-Ad68N-g51vCf01pWAU2MDdw/s1600/swp-template-01.PNG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 353px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzRn5ZsZ6LKK2gcAG1RHUHdfG7-LN3ukp1KQArDJgSxnYf6XLehPemJ5RmFgpBYhSge3_zvJzV2KRnG2Csln66RNB2eA-YO_ZawI6EIeo8IVOF-h-Ad68N-g51vCf01pWAU2MDdw/s400/swp-template-01.PNG" alt="" id="BLOGGER_PHOTO_ID_5712496529265752658" border="0" /></a><br />Note that you can make the file name identical to the domain ontology that it's for, but you should make sure that the base URI of that file is easily distinguished. I often add .spin to the end of the base URI. Checking the box that the "File will export SPIN Functions or Templates" will also give the file the .spin extension and register any contained templates globally in your workspace. Replace the namespace prefix from kennedys.spin to kenspin to make it a bit shorter.<br /><br />In that new file, we add the domain model (kennedys.ttl) to the imports. Then we create a SPIN template that encapsulates the query to get the children. This template needs one argument: the Person to get the children of. In order to define arguments, SPIN includes the recommended namespace prefix "arg". Right click on sp:arg in the Properties tree and create a sub-property arg:person.<br /><br />Then create a subclass of spin:SelectTemplates, called kenspin:GetChildren. Drag and drop the arg:person property from the Properties view onto the label spin:constraint on the form of that new class. This opens a dialog in which you can easily define the value type of the argument (kennedys:Person). Next, define the query as shown below:<br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKVivzJgMlphpyImTLtLgu-m_kc2F44jUn5GKFnH4sDXwnsOFXbwWmHvdZ5rV3zB_N5uj6QxN9FRgYe4bkDW7Ff7WwbpoXJDTFsot8k3BYcvEhpbqcQbLx7q3otuQK6i35WKM0CQ/s1600/swp-template-02.PNG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 325px; height: 400px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKVivzJgMlphpyImTLtLgu-m_kc2F44jUn5GKFnH4sDXwnsOFXbwWmHvdZ5rV3zB_N5uj6QxN9FRgYe4bkDW7Ff7WwbpoXJDTFsot8k3BYcvEhpbqcQbLx7q3otuQK6i35WKM0CQ/s400/swp-template-02.PNG" alt="" id="BLOGGER_PHOTO_ID_5712497702569686354" border="0" /></a><br /><br />The new SPIN template is now ready to be used elsewhere, also independently from SWP use cases. The SWP view definitions should go into a separate file. We create a new RDF/SWP (UISPIN) file with the following options:<br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsi9ztNZZv60WFDfnLlxkZJvEmeadx7DsJoyZGL-A0dDDTc3NZBB3zHwaQ6LKnCNOC9l0LPoxtlnUl_W-17tvGtrXcgFixJAn_Mpm-nuK6wGmTxmfr9K8iBahIwhknA1grWDHLvQ/s1600/swp-template-03.PNG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 350px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsi9ztNZZv60WFDfnLlxkZJvEmeadx7DsJoyZGL-A0dDDTc3NZBB3zHwaQ6LKnCNOC9l0LPoxtlnUl_W-17tvGtrXcgFixJAn_Mpm-nuK6wGmTxmfr9K8iBahIwhknA1grWDHLvQ/s400/swp-template-03.PNG" alt="" id="BLOGGER_PHOTO_ID_5712499189504054626" border="0" /></a><br /><br />Again, we can give it a similar namespace and file name as the domain ontology that it belongs to, but take care to keep base URI distinct and to shorten the prefix to something like kenui. In the new SWP file, we add the SPIN file from above to the imports. This will also import the Kennedys domain ontology.<br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqO-9yd9URHAaAac9OiOO6Oq5SkQrN14YHna2xNy6lltaRk7S70jX3BjHWTGChfbApIisLBn0y3gqybot0HLUOJirzXV5HNwO8aKkCWwhhU4GNvjVy3oNOjb1Lq70DQn5YOznYxg/s1600/swp-template-04.PNG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 123px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqO-9yd9URHAaAac9OiOO6Oq5SkQrN14YHna2xNy6lltaRk7S70jX3BjHWTGChfbApIisLBn0y3gqybot0HLUOJirzXV5HNwO8aKkCWwhhU4GNvjVy3oNOjb1Lq70DQn5YOznYxg/s400/swp-template-04.PNG" alt="" id="BLOGGER_PHOTO_ID_5712499496371839666" border="0" /></a><br />Next we create a subclass of ui:Element, called kenui:ChildrenList. This is a new user-defined SWP view that can be used with its own (HTML) tag <kenui:childrenlist> later. It again takes a Person as its argument - this time the person we want to display the children of.<br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-OMAOPpnM7Y9n8rpnHa03FvgaxJbEQ_3JZ81To4kHTZk5gklcuV7waAvDPw2z336b3JJONFveOCBiWsAfnJxXh_nHwrYRvJpSIGfIqALLyuO7YKGH6eA0HLa8XLD1r06_htnaKg/s1600/swp-template-05.PNG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 311px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-OMAOPpnM7Y9n8rpnHa03FvgaxJbEQ_3JZ81To4kHTZk5gklcuV7waAvDPw2z336b3JJONFveOCBiWsAfnJxXh_nHwrYRvJpSIGfIqALLyuO7YKGH6eA0HLa8XLD1r06_htnaKg/s400/swp-template-05.PNG" alt="" id="BLOGGER_PHOTO_ID_5712500075073305506" border="0" /></a>The ui:prototype of this view is considerably shorter than the original starting point because it no longer contains the SPARQL query. Instead it uses <a href="http://uispin.org/ui.html#call">ui:call</a> to invoke the SPIN template that we had defined earlier. ui:call takes the name of the template as one argument, and all other arguments (such as arg:person) will be passed into the template. The result of the ui:call tag is that the variable ?rs will contain the SPARQL result set from the query. This result set is then used in a ui:forEach loop to walk through all rows, producing one HTML LI tag for each entry.<br /><br />Putting this new SWP element into practice now is as simple as the following:<br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcpW7Wnx3avIRPlWjv2ZxZ66CunDr2QY3Vc_1SiVXB-T_RE5-ALbCrilBi1dQbxwXLWCO4zaG0HMEBPw7bY5XQakhzNgkxhsGo0TponebpDP_Nr5pbOF0xwySzIgd4057TvasOww/s1600/swp-template-06.PNG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 39px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcpW7Wnx3avIRPlWjv2ZxZ66CunDr2QY3Vc_1SiVXB-T_RE5-ALbCrilBi1dQbxwXLWCO4zaG0HMEBPw7bY5XQakhzNgkxhsGo0TponebpDP_Nr5pbOF0xwySzIgd4057TvasOww/s400/swp-template-06.PNG" alt="" id="BLOGGER_PHOTO_ID_5712502199779266258" border="0" /></a><br /><br />This pattern illustrates division of labor in web development teams: the HTML designer and the query expert only need to agree on a couple of names (the name of the template, the arguments and result variables), but apart from that they can do their own business independently. They work on different files - the SPIN logic goes into a .spin. file and the SWP layout goes into an .ui. file. The ontology itself is of course yet in another file and can be edited by a third group of people.Holger Knublauchhttp://www.blogger.com/profile/13180242480924209321noreply@blogger.com0tag:blogger.com,1999:blog-31416365.post-90384198696319388792011-07-05T10:57:00.000-07:002011-07-05T16:48:56.442-07:00Validating schema.org Microdata with SPIN<div>The new 3.5.1 version of <a href="http://www.topquadrant.com/products/TB_Composer.html">TopBraid Composer</a> introduces some initial features to import, browse, edit and analyze Microdata. I wrote about this in a <a href="http://composing-the-semantic-web.blogspot.com/2011/06/microdata-and-rdfa-in-topbraid-composer.html">previous blog entry</a> - if you want to try those features just download TBC's evaluation version, keeping in mind that Microdata support is still at an early stage and that, for example, the parser isn't fast yet. Today I will focus on a SPARQL-based approach for validating schema.org Microdata using <a href="http://spinrdf.org/">SPIN</a> inside of TopBraid.</div><div><br /></div><div>I have published a library of SPIN constraints at <a href="http://topbraid.org/spin/schemaspin">http://topbraid.org/spin/schemaspin</a>. This library currently includes 11 types of integrity constraints covering various aspects on the schema.org ontology, as shown below.</div><div><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtsE-dk1LW2kJ8_Ksyt1rNE00Yy6IfOOECkpJgWeg2DLwYCyVuOLmmli0QJ7Kb2OSir5Ms5c4Bgqoy3F3uO2MUkyGy-vWlxVWaDcvMe3CtZFMgAtdbjizVlnGOgu7z9T7VOAF1qA/s1600/schemaspin.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 146px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtsE-dk1LW2kJ8_Ksyt1rNE00Yy6IfOOECkpJgWeg2DLwYCyVuOLmmli0QJ7Kb2OSir5Ms5c4Bgqoy3F3uO2MUkyGy-vWlxVWaDcvMe3CtZFMgAtdbjizVlnGOgu7z9T7VOAF1qA/s400/schemaspin.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5623892389226042274" /></a></div><div>The most basic tests are making sure that schema.org properties can only be used at classes with matching domains, and that the values of those properties match their declared ranges. These tests alone may help you identify many potential errors at edit time. Another generic test is associated with owl:IrreflexiveProperty, making sure that a value of children, colleagues, follows, knows etc doesn't point to itself.</div><div><br /></div><div>Other tests check for various family relationships (e.g. children must be born after their parents, children cannot contain cycles and birthDate must be before deathDate), emails must match certain regular expressions, and the ranges of longitudes and latitudes. The following TBC screenshot shows an example of an invalid longitude:</div><div><br /></div><div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj90ZJUNKwBZE7u-zsXkVLOYFOarSg_UnQAerLLaNpvylqx-Xt9_gJi2NQj1u50jF4vMD3uV0tE9nCN_bsECn9QdTryoBYwNBbsga2YxNgvATeFdAyqpzWLC9COxoebrSFhV5k9eQ/s1600/schemspin-TBC.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 278px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj90ZJUNKwBZE7u-zsXkVLOYFOarSg_UnQAerLLaNpvylqx-Xt9_gJi2NQj1u50jF4vMD3uV0tE9nCN_bsECn9QdTryoBYwNBbsga2YxNgvATeFdAyqpzWLC9COxoebrSFhV5k9eQ/s400/schemspin-TBC.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5623895550216553954" /></a></div><div>A really powerful demonstration of ontology reuse and linkage is the constraint that validates currency codes. There is a finite vocabulary of those, including EUR and USD. The schemaspin ontology simply imports the <a href="http://qudt.org/">QUDT</a> namespace that already defines all of those abbreviations, and reports an error if an unknown currency is used on a Microdata page. The following screenshot shows the underlying SPIN constraint (note that this spin:constraint is attached to a property metaclass that marks all properties holding currencies as values):</div><div><br /></div><div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOUMHLqx-B0WlPDSGy3YbztByvRRxlBOnM-FDa-qRYABXiT_6Igt8gkGvqk8BfLSwtAgeOa1AkYdWNqovjzAv5mvbm4p7LlWeQNUYjPyHAqEksEu_M0uUeVfpbivPk9QHKe5akRQ/s1600/CurrencyConstraint.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 272px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOUMHLqx-B0WlPDSGy3YbztByvRRxlBOnM-FDa-qRYABXiT_6Igt8gkGvqk8BfLSwtAgeOa1AkYdWNqovjzAv5mvbm4p7LlWeQNUYjPyHAqEksEu_M0uUeVfpbivPk9QHKe5akRQ/s400/CurrencyConstraint.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5624205131072376386" /></a></div><div>The constraints above are just a beginning. Much more interesting constraints could be defined if more data is published on the Semantic Web, e.g. by asking the Sindice SPARQL end point with the SPARQL SERVICE keyword to validate that a link to a Person really describes a known http://schema.org/Person, or to compare prices to make sure that my offering of a product is currently the lowest price on the market. The open architecture of SPIN and the richness of SPARQL makes adding these and domain-specific constraints easy and enjoyable.</div>Holger Knublauchhttp://www.blogger.com/profile/13180242480924209321noreply@blogger.com0tag:blogger.com,1999:blog-31416365.post-33700928962276733552011-07-03T16:25:00.000-07:002011-07-03T16:25:00.487-07:00SPARQL Web Pages made easy<div><a href="http://uispin.org/">SPARQL Web Pages</a> (SWP, aka UISPIN) is a templating language for HTML and XML formats that operate on RDF data. In a nutshell, SWP makes it possible to embed SPARQL expressions and queries directly into web page snippets, and to link an RDF or OWL ontology with such SWP snippets. SWP can also be used to generate JSON callback results to support Ajax-style patterns. This basically means that application developers can cover the whole software stack ranging from model to control to view with RDF-based representations only.</div><br /><div>At TopQuadrant, we have meanwhile made substantial use of SPARQL Web Pages in internal and customer-facing projects, and have introduced several SWP enhancements with TopBraid 3.5. One thing that several people asked for was SWP support for stand-alone web pages that are not necessarily linked to specific classes in an ontology. In response to this, we have introduced *.swp files, which can be used like PHP or JSP documents with a TopBraid server.</div><div><br /></div><div>In order to create such SWP files, go to File > New > SPARQL Web Pages file. This will create a stub file with some content that will help you get started:</div><div><br /></div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEis1KKd20VXSJN_9TeNcpkfMmQ5BuIgP2TU9bXCluHrNDsKmIdQAhqzdIdWR2ocFpF9F11_xgJSyV9zpxUMWjYA11m1Z5bCHseubOUbCj7k4xnB47471RQ6fLuECaBSjXTCqqS2HQ/s1600/SWP-Editor.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 196px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEis1KKd20VXSJN_9TeNcpkfMmQ5BuIgP2TU9bXCluHrNDsKmIdQAhqzdIdWR2ocFpF9F11_xgJSyV9zpxUMWjYA11m1Z5bCHseubOUbCj7k4xnB47471RQ6fLuECaBSjXTCqqS2HQ/s400/SWP-Editor.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5623877070265251442" /></a>Through its base platform Eclipse, TopBraid Composer includes a powerful HTML editor, and TBC 3.5.1 includes syntax highlighting for SWP built-ins (see above, you may need to associate *.swp files with the HTML content type in the Eclipse preferences as described in the TBC Help).<div><br /></div><div>As soon as you have created this file, you can immediately execute it via the personal TopBraid Live server that is built into TopBraid Composer. Just visit http://localhost:8083/tbl/test.swp in your browser:<div><div><br /></div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgg-Xq-_NyQfOB1gqv6h8bZ4eK8No924HCB7q2XS839t3A_SItgGw1c2ZGmojqGr0iUgA1kEeyvCcGcEeSOPaDcSLxh-J4K5euUfEOflT0MhLDoGk0923DBWKUiNmmAGnCpM4AAww/s1600/SWP-Browser.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 229px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgg-Xq-_NyQfOB1gqv6h8bZ4eK8No924HCB7q2XS839t3A_SItgGw1c2ZGmojqGr0iUgA1kEeyvCcGcEeSOPaDcSLxh-J4K5euUfEOflT0MhLDoGk0923DBWKUiNmmAGnCpM4AAww/s400/SWP-Browser.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5623877695385004242" /></a>The example above takes one argument (test) and inserts this into the greeting. The expression {= ?test } will insert the current value of the SPARQL variable ?test into the output document. In our example, ?test is fetched from the URL arguments via the built-in function ui:param(). The demo page then creates a simple loop over all instances of kennedys:Person in the query graph and inserts them into an unordered HTML list. The actual query graph is specified using the ui:setContext tag - if this isn't present it will use the default graph.</div><div><br /></div><div>For a more complete live demo of SWP, visit <a href="http://spinservices.org:8080/spin/doc.swp">http://spinservices.org:8080/spin/doc.swp</a> providing documentation of the GoodRelations ontology:</div><div><br /><div style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1d7S530f2Gsp2NvbdOjcv-9ZxloEUluTSW9QSZwT0pN81EqpXPj2BhVcJ61pgdZHwTDgo7GEeTQeCNBDehloBE7YNEydeqCDJpiKgxN-lRPKx0bIRTBJcGw8w9zFp3npVbN9cww/s1600/SWP-Documentation.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 255px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1d7S530f2Gsp2NvbdOjcv-9ZxloEUluTSW9QSZwT0pN81EqpXPj2BhVcJ61pgdZHwTDgo7GEeTQeCNBDehloBE7YNEydeqCDJpiKgxN-lRPKx0bIRTBJcGw8w9zFp3npVbN9cww/s400/SWP-Documentation.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5623883920389191106" /></a></div></div><div>For anyone with experience in hand-editing HTML and JSP or PHP, SPARQL Web Pages should look quite familiar. In fact, SWP borrows ideas from other well-known languages such as loops, assignments, if-then-else branching and user-defined tags, but is 100% SPARQL. With RDF nodes as first-class citizens, this language is IMHO an attractive alternative to projects that use RDF as their primary data representation or integration format.</div></div>Holger Knublauchhttp://www.blogger.com/profile/13180242480924209321noreply@blogger.com0tag:blogger.com,1999:blog-31416365.post-40779996982503187302011-06-09T00:24:00.000-07:002011-06-09T02:40:19.834-07:00Microdata and RDFa in TopBraid Composer<div>The next release of <a href="http://www.topquadrant.com/products/TB_Composer.html">TopBraid Composer</a> will include comprehensive support for editing and processing <a href="http://schema.org/">schema.org</a> <a href="http://www.w3.org/TR/microdata/">Microdata</a>, and will also have improved support for <a href="http://en.wikipedia.org/wiki/RDFa">RDFa</a>. TopBraid is an extension of Eclipse and thus inherits a lot of goodness from the platform, including a very nice HTML editor. It was straight-forward and highly desirable to extend TopBraid with native support for those Web Data formats. Here is a preview of what it will look like.</div><div><br /></div><div><b><span class="Apple-style-span" style="font-size: large;">Working with Microdata and RDFa</span></b></div><div><br /></div><div>When I started exploring Microdata for <a href="http://knublauch.com/">my own web site</a>, I created a new Eclipse project within TopBraid Composer containing the HTML, CSS and image files for the site. </div><div><br /></div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYISWFx_vaWFuV_tI-bDZbVUIPa3vcDUK8HIQGxrnkajs0j1KZTlwd9rX9AU5rpCGUSe8uB3JZi81qHHVbJt-rduc11cNFxntNvFxOzbk4_6gBOoiegzIZVKW22hanCY3FPDfK8w/s1600/TBC-Navigator.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 210px; height: 243px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYISWFx_vaWFuV_tI-bDZbVUIPa3vcDUK8HIQGxrnkajs0j1KZTlwd9rX9AU5rpCGUSe8uB3JZi81qHHVbJt-rduc11cNFxntNvFxOzbk4_6gBOoiegzIZVKW22hanCY3FPDfK8w/s400/TBC-Navigator.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5616136586675409746" /></a><div>While I was adding the Microdata tags to the HTML documents, I quickly discovered that RDF based tooling can be extremely helpful to make sure that the published metadata is consistent and of good quality. For example, data about entities (such as the http://schema.org/Person about myself) is split across multiple HTML pages: the <a href="http://knublauch.com/">front page</a> contains my address, but my <a href="http://knublauch.com/personal.html">personal page</a> contains information about my children. In such cases it is important that both pages use the same identifiers for the same Linked Data entities. This becomes even more important if we want to link to external standard vocabularies, such as ontologies about units, countries or product categories.</div><div><br /></div><div style="text-align: center;"><span class="Apple-style-span" style="font-size:medium;"><b>Linked Web Data is much more useful than isolated data snippets on individual pages.</b></span></div><div><br /></div><div>As a result of this, I introduced the notion of Web Data Sites into TopBraid Composer - collections of pages in the same folder and its sub-folders. Right click on the project above and select New > Microdata Site File (or RDFa Site File). This opens a wizard with an option for default ontologies to include. For Microdata this is obviously the schema.org namespace, but any other RDF vocabulary can be added later:</div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfEuYn9Y5D4MyWDFpYbXSFkwfNCYHuYTBwTtY_Y1hD2vlqouLg5nUbqqNIBnGyl0woi4o5UCMFt-Ge1DdGGNzW1f2WI1O-rLYQezwp7Xye3BLA2yAu6V5nvtpDNK6Y5PtKcQK5Cw/s1600/NewMicrodataSite.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 284px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfEuYn9Y5D4MyWDFpYbXSFkwfNCYHuYTBwTtY_Y1hD2vlqouLg5nUbqqNIBnGyl0woi4o5UCMFt-Ge1DdGGNzW1f2WI1O-rLYQezwp7Xye3BLA2yAu6V5nvtpDNK6Y5PtKcQK5Cw/s400/NewMicrodataSite.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5616137437703860178" /></a>This creates a site file (*.mds) that acts as a placeholder for all RDF triples on the HTML pages within the same folder and its subfolders. The site file can be opened like any other RDF data source, it can be imported into other data models, etc. When opened, it will scan the HTML files and always automatically stay up to date when the data on the HTML is changed.<br /><div><br /></div><div>The screenshot below (click on the image for the full size) shows some of the new TBC capabilities in practice.</div><div><br /></div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRYEEeeC_tZ2SQmcL-DzgTLarTnt_rHTr17ayr6ejUyaQmxgs2PndrkOJzDHTan_IEfrt1cE3UKNgqpw0e8RTj0TXaDraP6ImfFyWlsLnlY74r93qYP4uKNqSlUNF1MsPvU_tH8g/s1600/TopBraidComposer-Microdata.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 225px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRYEEeeC_tZ2SQmcL-DzgTLarTnt_rHTr17ayr6ejUyaQmxgs2PndrkOJzDHTan_IEfrt1cE3UKNgqpw0e8RTj0TXaDraP6ImfFyWlsLnlY74r93qYP4uKNqSlUNF1MsPvU_tH8g/s400/TopBraidComposer-Microdata.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5616124755982129938" /></a>You can see that TopBraid has built-in views to browse the class hierarchy, properties and instances. These are powerful mechanisms to navigate through the data space that is encoded in the HTML pages. In the example above, you can see that my current Microdata pages contain information about three Persons, as well as various address and location objects. The class tree shows the number of instances of each class. A double-click on an instance will display it on a form. You can see the form view of the resource http://knublauch.com (representing myself as a schema:Person) on the right. Here is a larger view, with the details of one of the children objects opened up:<div><br /></div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsydrtw7deiiiXwvyPEXsGUhJXljsVkF_zIcYd09afLyT5wnZ3l2V9UWjQFGgHaKMiunTuWE2yuM0Wy3doDI-6QDpbqegfkZiAtNaIIsnO7JROfWgG_KR7GFXITPKYFLksDl6BBg/s1600/TBC-Form.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 382px; height: 344px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsydrtw7deiiiXwvyPEXsGUhJXljsVkF_zIcYd09afLyT5wnZ3l2V9UWjQFGgHaKMiunTuWE2yuM0Wy3doDI-6QDpbqegfkZiAtNaIIsnO7JROfWgG_KR7GFXITPKYFLksDl6BBg/s400/TBC-Form.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5616139745225685522" /></a><br /><div>Alternative views such as graphs and smart browser displays are also built-in. Here is a TBC graph view of some instances:</div><div><br /></div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh12AyQdzFHsYrD9KLnrpAFX8mA5DtCnrvXkFvbqCYvQDfCVVU63NaZKXPTHjH3tTPiKOZn4-BcFc7tlytJu2fUDLR7QvbxnHbyDBtgo_X_aIngoBjGEllEi_ROAgSByVmAv6DZEw/s1600/TBC-Graph.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 144px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh12AyQdzFHsYrD9KLnrpAFX8mA5DtCnrvXkFvbqCYvQDfCVVU63NaZKXPTHjH3tTPiKOZn4-BcFc7tlytJu2fUDLR7QvbxnHbyDBtgo_X_aIngoBjGEllEi_ROAgSByVmAv6DZEw/s400/TBC-Graph.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5616140403663911298" /></a><b><br /></b><div><b><span class="Apple-style-span" style="font-size: large;">Analyzing Web Data with SPARQL and SPIN<br /></span></b><div><br /></div><div>You can also run SPARQL queries over this data:<div><br /><div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizaQ4ZeNGD0SSCSNdNiWyjCKOcFzhsWQPI-qFrJp9pAX8Le372gzEPypW-Te6nTHp3DUHlsRE8dBrJC3y6OtDpEB3yoddYehVuvClSox6uXXpaEQ31Eafc43o0WkWIGhv2f_Jrig/s1600/TBC-SPARQLView.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 230px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizaQ4ZeNGD0SSCSNdNiWyjCKOcFzhsWQPI-qFrJp9pAX8Le372gzEPypW-Te6nTHp3DUHlsRE8dBrJC3y6OtDpEB3yoddYehVuvClSox6uXXpaEQ31Eafc43o0WkWIGhv2f_Jrig/s400/TBC-SPARQLView.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5616141128123917522" /></a><div>We have a lot of <a href="http://spinrdf.org/spinstack.html">SPARQL-based features</a> built into the TopBraid platform, including the rule and constraint language <a href="http://spinrdf.org/">SPIN</a> (now a W3C Member Submission). SPIN is useful to define model-based integrity constraints, and I have started to create a SPIN constraints library for the schema.org namespace. Currently this checks that the value type of properties on the HTML pages matches the range defined by the ontology, but more checks will be added, for example regular expressions of emails, country abbreviations etc. More on this in a separate entry some day.</div><div><br /></div><div><b><span class="Apple-style-span" style="font-size: large;">Editing Microdata and RDFa</span></b></div><div><br /></div><div>Once you have checked constraints and the system reports a violation, you can navigate to the source of the violation on the form of the relevant instance. From those forms, you simply need to double-click on the icon to the left of the value to navigate to the HTML source code:</div><div><br /></div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkC2bq3nuxcd_n3QZSAl55lQJP2FPWEFRho8zsqBfa5-LhPpIYmtBSvp0wL1XTh26RlWYEClPsNHJlzG2_Z__1N7ovBBH_JkHM_Qm8SqcTFd1Fq2SziACFojiFsbK1cOPLLjtCYQ/s1600/Screen+shot+2011-06-09+at+7.03.42+PM.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 163px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkC2bq3nuxcd_n3QZSAl55lQJP2FPWEFRho8zsqBfa5-LhPpIYmtBSvp0wL1XTh26RlWYEClPsNHJlzG2_Z__1N7ovBBH_JkHM_Qm8SqcTFd1Fq2SziACFojiFsbK1cOPLLjtCYQ/s400/Screen+shot+2011-06-09+at+7.03.42+PM.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5616143318211182786" /></a>At this stage, the circle is completed and are in HTML document where you can fix problems (e.g. a misspelled email address). Save the HTML file, and the RDF triple (on the form and elsewhere) will update automatically.<br /><div><br /></div><div>The HTML editor in TopBraid Composer has been enhanced with syntax highlighting for the Microdata attributes such as itemprop. And more is on its way...</div><div><div><br /></div><div><div><b><span class="Apple-style-span" style="font-size: large;">Harvesting Microdata and RDFa from the web</span></b></div><div><br /></div><div>In addition to editing and processing local Web Data files, TopBraid can also be used to work with external mark-up from existing pages. TBC Version 3.5 had already introduced the <a href="http://composing-the-semantic-web.blogspot.com/2011/04/topbraid-composers-web-data-basket.html">Web Data Basket</a>, and we have extended this to also support Microdata. The mechanism is simple yet powerful: you install a small Firefox extension that will send the pages you visit to your locally running TopBraid Composer. This will collect all RDF metadata contained on the visited pages, and make it available to the RDF, OWL and SPARQL machinery of TBC. This means you can simply browse the web and you will automatically get the stream of RDF triples into your working environment.</div></div></div></div></div></div></div>Holger Knublauchhttp://www.blogger.com/profile/13180242480924209321noreply@blogger.com0tag:blogger.com,1999:blog-31416365.post-77137002036423864362011-04-26T22:41:00.000-07:002011-06-02T19:57:44.051-07:00Faceted Search with TopBraid and SWPMany Semantic Technology companies offer some kind of faceted browsing tool. With <a href="http://www.topquadrant.com/products/release_notes/v3_5.html">TopBraid 3.5</a> it was time for TopQuadrant to say "me too", and add some unique capabilities into the mix.<div><br /></div><div>The main idea of faceted browsing is to allow users to narrow down a set of objects by selecting properties that the sought-after objects must possess. For example, if you search for people in the infamous <a href="http://topbraid.org/examples/kennedys">Kennedy ontology</a>, you may want to find all instances of Person that went to the same university and share the same profession. TopBraid's faceted search component follows a user interface paradigm made popular by <a href="http://www.freebase.com/labs/parallax/">FreeBase Parallax</a>: you start with a set of all Persons and the system will compute how many matches are in each category. Clicking on a category will narrow down the set, and you can add the next condition. The following screenshot illustrates this, with the facet "alma mater" narrowed down to "Harvard University".</div><div><br /></div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizjQH1BgcXb816gySk0HJ-IUiyPQa5pKPyjrwD6U2MarNqdIj4lNKcrep8eYquRsfK9OzwgrPG3dVtCRHX-JLsJZRM6J4ZUVWLMcq3rZftqTr67etI2UkwiAoS_P_BV-ytT-yQ7Q/s1600/Facets-1.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 275px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizjQH1BgcXb816gySk0HJ-IUiyPQa5pKPyjrwD6U2MarNqdIj4lNKcrep8eYquRsfK9OzwgrPG3dVtCRHX-JLsJZRM6J4ZUVWLMcq3rZftqTr67etI2UkwiAoS_P_BV-ytT-yQ7Q/s400/Facets-1.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5600136794067578786" /></a>TopBraid's faceted search is implemented by a collection of TopBraid Live servlets and a JavaScript UI library. What you see on the screen above is in fact a web browser embedded into TopBraid Composer. The default stylesheet is simple and can be customized, and it's also possible to use the same JavaScript library in completely different web applications.<div><br /></div><div>One distinguishing capability of TopBraid's Faceted Search support is its customizability. <a href="http://uispin.org/">SPARQL Web Pages (SWP)</a> technology can be used to customize the visual appearance of the preview results on the right hand side. A key benefit of SWP is the linkage between ontologies and user interface snippets. Basically, SWP allows you to attach HTML snippets to any RDFS or OWL class in your domain model using the property ui:instanceView, and the system is then able to dynamically select the best suitable visualization for any object that it gets. For example, the visualization for kennedys:Person can be changed as shown below.</div><div><br /></div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKTNS9PXYTjJiXnMkTWiN-rcy9RxDvWgMpBFwQukw3H1vSL7qjQJuanB49DtsTAmILRz723QHxY0MkoN5O0GWj7vMaqH8lcEelUrA78256Ze0F0WlxjTW6ZRrps7rgc1YSh-k_Ew/s1600/Facets-2.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 147px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKTNS9PXYTjJiXnMkTWiN-rcy9RxDvWgMpBFwQukw3H1vSL7qjQJuanB49DtsTAmILRz723QHxY0MkoN5O0GWj7vMaqH8lcEelUrA78256Ze0F0WlxjTW6ZRrps7rgc1YSh-k_Ew/s400/Facets-2.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5600146220166005426" /></a>The faceted search component looks for visualizations marked with ui:id="facetSummary", and will display them as shown below.<div><br /></div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPQtz3UZmcOBXCYsBxwS8FJ-OYRazda2nNq9vRM9l0e5m2TcwDa6_M0UzSdd4UmlypTMhjuKYUUPm3-JLjV0RiS09KAHkp5EpjwPg4pxyt-mDHmgJeCRHOcZBRyDN4bZw1vrneQw/s1600/Facets-3.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 199px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPQtz3UZmcOBXCYsBxwS8FJ-OYRazda2nNq9vRM9l0e5m2TcwDa6_M0UzSdd4UmlypTMhjuKYUUPm3-JLjV0RiS09KAHkp5EpjwPg4pxyt-mDHmgJeCRHOcZBRyDN4bZw1vrneQw/s400/Facets-3.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5600146647465004562" /></a>Further customizations are possible without any programming: For example you can specify which properties shall be visible by default, and which properties shall not be selectable as facets.<br /><div><br /></div><div>There is more to be said about this new capability. But if you just want to get started, use TBC-ME 3.5, select the class that you want to search instances of, switch to the Browser tab and pick the facet.ui:SearchView view in the drop down list. Note that on Windows this currently does not work because Eclipse includes an outdated internal web browser. Please use the button <b>Open current page in external browser. </b>Like with any new feature, we appreciate your feedback.<div><div><br /></div></div></div>Holger Knublauchhttp://www.blogger.com/profile/13180242480924209321noreply@blogger.com0tag:blogger.com,1999:blog-31416365.post-80200872652160226012011-04-26T22:10:00.000-07:002011-04-26T22:34:54.433-07:00TopBraid Composer's Web Data Basket: Collecting Linked Data while you browseOne of the little new features in <a href="http://www.topquadrant.com/products/release_notes/v3_5.html">TopBraid Composer 3.5</a> is the <b>Web Data Basket</b> view. This can be used to incrementally download Linked Data (either RDFa or RDF) while browsing the web. The best way to experience this is by getting a small <a href="http://topbraid.org/mozilla">TBC Firefox extension</a>. This will add a tiny TopBraid button to the lower right corner of your browser.<div><div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiztZjF7D_5bUVBpW8MTIKGzeL_AfigpywRR4NJ2N-9DkaiowBGxGKWjKeEAfpgbofFZRVkygti3BXYzCvJA257rsItPPUMy_97hStXRJqjTHPjFTAcGKOhwAwfr8PINvxa877Hnw/s1600/WebDataBasket-1.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 247px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiztZjF7D_5bUVBpW8MTIKGzeL_AfigpywRR4NJ2N-9DkaiowBGxGKWjKeEAfpgbofFZRVkygti3BXYzCvJA257rsItPPUMy_97hStXRJqjTHPjFTAcGKOhwAwfr8PINvxa877Hnw/s400/WebDataBasket-1.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5600129355377310658" /></a></div><div>Click on this button while TopBraid Composer is executing, and all RDF data encoded on the currently visited page will be added to TBC's Web Data Basket:</div></div><div><br /></div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5JiYPnll3iFlv7vP4T72MiOLKZQhZWMCsfi8_Ls4_NxtVy8P0c5X8OSB3yopWdwl-0jt-QoWGfdGYCXQ0gurJRSqGGPfIdfC8wgWS0i3zTdm2YueIgqBM946YIAUwtWKdgHQdnQ/s1600/WebDataBasket-2.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 129px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5JiYPnll3iFlv7vP4T72MiOLKZQhZWMCsfi8_Ls4_NxtVy8P0c5X8OSB3yopWdwl-0jt-QoWGfdGYCXQ0gurJRSqGGPfIdfC8wgWS0i3zTdm2YueIgqBM946YIAUwtWKdgHQdnQ/s400/WebDataBasket-2.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5600129651131693282" /></a>While this Basket displays the raw triples, it also has options to add the loaded triples into the current model. For example, you will get a proper foaf:Person for David Bowie if you visit his DBpedia page:<div><br /></div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZq5KG7VNfddM0AQr45S3YgBfwVT2sqfz3VWmvi3wuJy-NwnuJP5qjF32nc0i1r7LqL1EQZpjSAvThPL89kzxkVQYw8BE1R38Ka-oClaODENwwU5yM8fVD-x75JJuMx-sV1LC0YA/s1600/WebDataBasket-3.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 229px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZq5KG7VNfddM0AQr45S3YgBfwVT2sqfz3VWmvi3wuJy-NwnuJP5qjF32nc0i1r7LqL1EQZpjSAvThPL89kzxkVQYw8BE1R38Ka-oClaODENwwU5yM8fVD-x75JJuMx-sV1LC0YA/s400/WebDataBasket-3.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5600130590762439026" /></a>In order to facilitate the use of this data, TopBraid Composer will automatically add missing imports to namespaces such as foaf and skos. When you follow a hyperlink in your web browser, the basket will get more content. This means that the system will accumulate any Linked Data into TopBraid as you navigate through the web.<div><div><div><br /></div></div></div><div>This little Web Data Basket makes it easy to collect Linked Data without having to leave your favorite tools. I think it provides a fine example of how Linked Data could be used, e.g. to build up a shopping list of products backed with <a href="http://www.heppnetz.de/projects/goodrelations/">GoodRelations</a> data.</div>Holger Knublauchhttp://www.blogger.com/profile/13180242480924209321noreply@blogger.com0tag:blogger.com,1999:blog-31416365.post-22780971423815238692011-04-21T16:28:00.000-07:002011-04-21T17:18:16.728-07:00SPINMap: SPARQL-based Ontology Mapping with a Graphical NotationOne of the new features in the upcoming TopBraid 3.5 release is called SPINMap. <b>SPINMap</b> is a SPARQL-based language to represent mappings between RDF/OWL ontologies. These mappings can be used to transform instances of source classes into instances of target classes. This is a very common requirement to create Linked Data, for example starting with spreadsheets, XML files or databases, but also from one domain-specific ontology into a more generic one. As a first impression, here is a picture of SPINMap in action:<div><br /></div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1x2MFiYpat69ak1963RzFnONwgTSma8Gp8BfVjPlsXYY62CUI81Hlal1M_sYRgIO8yPvquC2nZEMD42Fuh0FIYhAX8YEt11AfC_Koa18HYLGrRNmIwIoiuT6js68Pu9YELHeCEQ/s1600/Screen+shot+2011-04-21+at+4.04.05+PM.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 260px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1x2MFiYpat69ak1963RzFnONwgTSma8Gp8BfVjPlsXYY62CUI81Hlal1M_sYRgIO8yPvquC2nZEMD42Fuh0FIYhAX8YEt11AfC_Koa18HYLGrRNmIwIoiuT6js68Pu9YELHeCEQ/s400/Screen+shot+2011-04-21+at+4.04.05+PM.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5598188519807034034" /></a><br /><div><div>If you would like to learn about this with a visual demo, please take a look at the</div><div><br /></div><div style="text-align: center;"><b><a href="http://vimeo.com/22695742">SPINMap Tutorial Video</a></b></div><div><br /></div><div>In the rest of this blog entry I will cover similar content to the video, but with screenshots and prose.</div><div><br /></div><div><b>Introduction to SPINMap</b></div><div><br /></div><div>SPARQL is a rich language that can be used for many purposes. The SPARQL CONSTRUCT keyword is particularly useful to define rules that map from one graph pattern (in the WHERE clause) to another graph pattern. This makes it possible to define sophisticated rules that map instances from one class to instances of another one.</div><br /><div>The <a href="http://www.w3.org/Submission/spin-overview/">SPIN framework</a> provides several mechanisms that make the definition of such SPARQL-based mapping rules easier. In particular, SPIN makes it easy to associate mapping rules with classes, and SPIN templates and functions can be exploited to define reusable building blocks for typical modeling patterns.</div><br /><div>The SPINMap vocabulary (http://spinrdf.org/spinmap) is a collection of reusable design patterns that reflects typical best practices in ontology mapping. SPINMap models can be executed in conjunction with other SPARQL rules with any SPIN engine. The main advantage of SPINMap is that it provides a higher-level language that is suitable to be edited graphically. TopBraid Composer 3.5 provides a visual editor that makes it easy to establish ontology mappings using drag and drop, and filling in forms.</div><br /><div>It is a good practice to store the ontology mapping rules in files separate from the source and target files. The mapping file only needs to import the SPINMap namespace (which in turn imports SPIN etc). The easiest way to get started is to use <b>File > New > RDF/OWL/SPIN File...</b> and then to activate the check box for "SPINMap Ontology Mapping Vocabulary", as shown below.</div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWqVffYUqklQBHPLvohkb5-_FLuWQwPQygTe2SE80-XFfE4caVFfnai2OtupjZd233ZlkSCQvlDaWKVOcA-N9Iu15uW0oRyA6HwuauuPLfL_HNT9gygH7SEDazR-F5mdQL3gBrgQ/s1600/SPINMap-CreateFile.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 383px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWqVffYUqklQBHPLvohkb5-_FLuWQwPQygTe2SE80-XFfE4caVFfnai2OtupjZd233ZlkSCQvlDaWKVOcA-N9Iu15uW0oRyA6HwuauuPLfL_HNT9gygH7SEDazR-F5mdQL3gBrgQ/s400/SPINMap-CreateFile.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5598189477747103362" /></a><div>This will create an empty file importing <code>http://topbraid.org/spin/spinmapl</code>. As a next step, you should drag the source and target ontologies into the Imports view so that those get imported into the mapping ontology. Then select the class you want to start mapping, and switch to the Diagram tab. In the example below, the source ontology A defines a class <code>a:Person</code>, and we want to map it into the target class <code>b:Customer</code>.</div><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0No3wfiPsvPOtVIUT61S232FeiCxoErE7j1aAInNZpMXxsD60Ffhca1K_LIRCG_ja-RwJ-UOnqQeE7PEP6pev_9_3DplNceyHD3zrSVfyrpGVSnPa1UBAcXcdWIUwjGAEuS4ktw/s1600/SPINMap-1.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 258px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0No3wfiPsvPOtVIUT61S232FeiCxoErE7j1aAInNZpMXxsD60Ffhca1K_LIRCG_ja-RwJ-UOnqQeE7PEP6pev_9_3DplNceyHD3zrSVfyrpGVSnPa1UBAcXcdWIUwjGAEuS4ktw/s400/SPINMap-1.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5598189110850976882" /></a><br /><div>Use drag and drop (e.g. from the Classes view) to add other classes to the Diagram. If the SPINMap namespace is present, the Diagram will provide additional capabilities and use a different layout algorithm than usual. If you move the mouse over a class, a triangular anchor point will appear in the upper right corner of the class box. It will turn green if you move the mouse over it, and if it can be made the source of a mapping. Click on this and keep the mouse button pressed to establish a link to another class. Move the mouse over the incoming upper anchor of the target class and release the mouse. A dialog like the one below will appear.</div><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-E2zIGMxeMbgJyK7_5aOerN5o6oBN4xS9ljg24G4rEHsQaEaRCOhshHTRJHzeEftWCrvxTSTa7qLJfKVezn9w93GuigwyUfFedhRPk7Z1DzeVS0bGNdKyajR6wRQYEKlYICECFg/s1600/SPINMap-2.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 298px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-E2zIGMxeMbgJyK7_5aOerN5o6oBN4xS9ljg24G4rEHsQaEaRCOhshHTRJHzeEftWCrvxTSTa7qLJfKVezn9w93GuigwyUfFedhRPk7Z1DzeVS0bGNdKyajR6wRQYEKlYICECFg/s400/SPINMap-2.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5598189728258851090" /></a><br /><div>This dialog is used to create a "mapping context" that is later used to determine how the target instances shall be selected from the source instances. In particular this is used to construct URIs from the values of a given resource, e.g. so that <code>a:Instance-0-1</code> is turned into <code>b:John-Smith</code>. The dialog provides a collection of target functions that can be used for that purpose. You simply need to pick an appropriate function and fill in the blanks to establish a mapping context. In the example screenshot, a new URI is constructed from the values of the source properties <code>a:firstName</code> and <code>a:lastName</code> and a provided URI template. This assumes that those properties together serve as unique identifiers, similar to primary keys in a database. Other algorithms can be created if needed through SPIN functions.</div><br /><div>As soon as you have filled in all required arguments of the mapping context function, the preview panel of the dialog will give you an idea of how the resulting values will look like. When you are happy with this, press OK.</div><br /><div>The resulting context will be displayed with a yellow graph node as shown below.</div><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP1ekRGThqE5EZnmzgzkrWFM2GsKGCKKCxrcNGY5HJRFpDHhD8veju6mgJpVazgIk9Ra78at0jkcqQas44axrSBHE9jfqRVv2QAR-7ZFoeBkYgKTNWlYjuzjt9uM5hAfKGZ3Rq4g/s1600/SPINMap-3.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 134px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP1ekRGThqE5EZnmzgzkrWFM2GsKGCKKCxrcNGY5HJRFpDHhD8veju6mgJpVazgIk9Ra78at0jkcqQas44axrSBHE9jfqRVv2QAR-7ZFoeBkYgKTNWlYjuzjt9uM5hAfKGZ3Rq4g/s400/SPINMap-3.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5598189916550318722" /></a><br /><div>If you ever need to edit this context node again, e.g. to change the URI template, just double-click on it. Right-clicking the node opens a context menu with an option to delete it.</div><br /><div>Once a context has been established between two classes, the user interface makes it possible to add transformations. In the example above, the source class has a property <code>a:dob</code> that holds date of birth values as raw strings, such as "30/04/1985". We want to map this into the target property <code>b:birthDate</code>, which is a well-formed <code>xsd:date</code> in the format "1985-04-30". TopBraid's SPARQL library provides a built-in function <code>spif:parseDate</code> to make this task easier. Use the mouse to draw a connection from <code>a:dob</code> to <code>b:birthDate</code>. A dialog such as the following will appear.</div><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibthI0454jnP4fshCmgEoa_lZCkJfkHX1NI52zm-G854V5LNWyJx4ebUtuMIEoPXDuDGsJgidHx8VU2W5offntFTt_OzFo8BT03pJKrPQcEjuXQ9m2uZIbR1gwRWC3QR6TzSn4uw/s1600/SPINMap-3.5.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 310px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibthI0454jnP4fshCmgEoa_lZCkJfkHX1NI52zm-G854V5LNWyJx4ebUtuMIEoPXDuDGsJgidHx8VU2W5offntFTt_OzFo8BT03pJKrPQcEjuXQ9m2uZIbR1gwRWC3QR6TzSn4uw/s400/SPINMap-3.5.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5598190140006607314" /></a><br /><div>In this dialog you can either manually select a transformation function, or check if the system has any suggestions for you, on the Suggestions tab. In this case, the system suggests <code>spif:parseDate</code> with pre-defined patterns to convert raw dates into valid <code>xsd:date</code> literals. Pressing OK, this creates a mapping transformation as shown below.</div><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjF_W2tnMOaRuHXFy23iq6Zb8WNu92WpimQLjxHmnvDrifNsX8xYbwB2aBZQRjSh4MjTF_fdmNN6yUTZBYlLqoTEDJGLhdIApLvN_MtdK4t81DBuFqYbLz0jR_XTy3up3NXaG-02Q/s1600/SPINMap-4.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 135px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjF_W2tnMOaRuHXFy23iq6Zb8WNu92WpimQLjxHmnvDrifNsX8xYbwB2aBZQRjSh4MjTF_fdmNN6yUTZBYlLqoTEDJGLhdIApLvN_MtdK4t81DBuFqYbLz0jR_XTy3up3NXaG-02Q/s400/SPINMap-4.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5598190326512364066" /></a><br /><div>At any point in time, TopBraid Composer makes it easy to try the mapping out. Assuming TopSPIN is the selected inference engine, just press the <b>Run Inferences</b> button in the main tool bar to see the results.</div><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCWhiQWTIJhNZTc9_Z3eU1SdqWCkARclc7vGcuuCrblI6onyVU7VHoE3ILLJzcUj1cXsyrGpLcxPTjXKGgxAUIB_qflI6JqkraHGI3LfblW_G6ewZPsOtDmo3vvRIbUhwCe1SBbQ/s1600/SPINMap-5.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 100px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCWhiQWTIJhNZTc9_Z3eU1SdqWCkARclc7vGcuuCrblI6onyVU7VHoE3ILLJzcUj1cXsyrGpLcxPTjXKGgxAUIB_qflI6JqkraHGI3LfblW_G6ewZPsOtDmo3vvRIbUhwCe1SBbQ/s400/SPINMap-5.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5598190478608010882" /></a><br /><div>As you can see above, each instance of the <code>a:Person</code> class has been mapped into a corresponding instance of <code>b:Customer</code>. The URI of the target resources has been generated using the string insertion template based on first name and last name. Furthermore, proper birth dates have been generated from the raw source strings. The context menu of the Inferences view provides options to assert the resulting RDF triples if desired, or you can use the Triples View to move them elsewhere.</div><br /><div>It is possible to add any number of other transformations in similar ways. Some transformations take more than one argument. In that case, additional input anchor points will be displayed, as shown for the node "concat with separator" below.</div><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoHKHGZv4HiG-NIAPbVoBe8oX0eYLbi9uU9oWUwAHlMXAucr6kq5k1ehYbK8O_oy1hmposZ560TLsi7N5hepgL5LujAaH8qEBx_b3283ot-jy3C9LRFqGNPR6N2BWRHonSc8GPIQ/s1600/SPINMap-6.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 193px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoHKHGZv4HiG-NIAPbVoBe8oX0eYLbi9uU9oWUwAHlMXAucr6kq5k1ehYbK8O_oy1hmposZ560TLsi7N5hepgL5LujAaH8qEBx_b3283ot-jy3C9LRFqGNPR6N2BWRHonSc8GPIQ/s400/SPINMap-6.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5598190648483776562" /></a><br /></div><div>Note that a complex example like above uses a number of different design patterns. Some additional of those patterns are explained in the <b><a href="http://vimeo.com/22695742">tutorial video</a></b>, that I would strongly recommend if you want to save time with this technology.</div><br /><div><b>Understanding and Extending SPINMap</b></div><br /><div>The mini tutorial above might be enough for many users to get started. For advanced users with knowledge of SPIN, the following background may be helpful to understand how SPINMap works, and how it can be extended.</div><br /><div>SPINMap is an entirely declarative application of SPIN. This means you can explore the mappings generated by the visual editor from an RDF perspective, e.g. using TBC forms. In the example above, the form for <code>a:Person</code> displays a collection of SPIN Template calls:</div><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhl0fv0ZVXcy6XXEIBP4Nqef81xia3WjCTINGR_0IEHJFq6GT3Epkjmz-WEbBClEfEI22oQlkcDal55Kw1MYzupIh220LKbeJ7emHEzBhqO9_swZxfpYmML6DXk4yS6kfxfDxaStw/s1600/SPINMap-7.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 117px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhl0fv0ZVXcy6XXEIBP4Nqef81xia3WjCTINGR_0IEHJFq6GT3Epkjmz-WEbBClEfEI22oQlkcDal55Kw1MYzupIh220LKbeJ7emHEzBhqO9_swZxfpYmML6DXk4yS6kfxfDxaStw/s400/SPINMap-7.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5598192698984588338" /></a><br /><div>You can drill into the templates by opening up the + sign that appears when you hover the mouse over the template icon.</div><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTTd8Pa_KYGYrC2nq9L1hrOAy-IOw3rBVhtw1pJArPC6KyWQiQd-n6K32uX02IH-1_5rOLLcucqMbUFhF3wUX4SD_pkvJz2oCtkmVZkmfAm3NyYtGb-Y4t0hX-4AuCTsQPDpTJEA/s1600/SPINMap-8.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 225px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTTd8Pa_KYGYrC2nq9L1hrOAy-IOw3rBVhtw1pJArPC6KyWQiQd-n6K32uX02IH-1_5rOLLcucqMbUFhF3wUX4SD_pkvJz2oCtkmVZkmfAm3NyYtGb-Y4t0hX-4AuCTsQPDpTJEA/s400/SPINMap-8.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5598192855509409506" /></a><br /><div>The example above illustrates that SPINMap is based on a (small) collection of generic templates, such as <code>spinmap:Mapping-2-1</code> which represents a mapping from 2 source properties into 1 target property. Each of those templates a linked to a <code>spinmap:Context</code> which is used at execution time to determine the target URIs. Furthermore, the argument <code>spinmap:expression</code> points to a SPARQL expression, SELECT or ASK query, or even a constant URI or literal that is used to compute the target value from the source value(s). The SPINMap templates are using the function <code>spin:eval</code>to evaluate those expressions at execution time. When executed, the expression will be invoked with pre-assigned values for <code>?arg1</code>, <code>?arg2</code> etc, based on the current values of <code>spinmap:sourcePredicate1</code> on the source instances.</div><br /><div>Since in practice any SPARQL function can be used as <code>spinmap:expression</code>, users can also add their own SPIN functions where appropriate. It is also possible to use the built-in SPARQL functions such as <code>xsd:string()</code>.</div><div>The mapping context uses a similar mechanism, also based on <code>spin:eval</code> to create target URIs. You can open any instance of <code>spinmap:Context</code> to see how this is done.</div><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhO9AXvAfKdeEHviS33kl6LKYrpesq0jpijqvJgErR6Yp66SomkE1xld9nRmXGZPzLETfJOAUCU5fHKY3HGVTdIl6Uc0deAXJtZ-jaivUXGVcppSXBo7C1WIaRkuVtu_t-FgEAJMg/s1600/SPINMap-9.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 297px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhO9AXvAfKdeEHviS33kl6LKYrpesq0jpijqvJgErR6Yp66SomkE1xld9nRmXGZPzLETfJOAUCU5fHKY3HGVTdIl6Uc0deAXJtZ-jaivUXGVcppSXBo7C1WIaRkuVtu_t-FgEAJMg/s400/SPINMap-9.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5598193022289360210" /></a></p><div>In the example above, the target function <code>spinmapl:buildURI2</code> is used to derive a new URI from two input properties and a template. You are free to define your own target functions there, as long as they are instances of <code>spinmap:TargetFunction</code> (and subclass of <code>spinmap:TargetFunctions</code>).</div><br /><div>If you are writing your own functions, or want to make the system smarter, you can add your own <code>spinmap:suggestionXY</code> values to the functions. These are SPARQL CONSTRUCT queries that may construct zero or more instances of the function, with partially filled in fields, as well as a <code>spinmap:suggestionScore</code>. See the function <code>spif:parseDate</code> for an example of what can be done with this mechanism.</div>Holger Knublauchhttp://www.blogger.com/profile/13180242480924209321noreply@blogger.com0tag:blogger.com,1999:blog-31416365.post-36465920881768968292011-04-04T17:12:00.000-07:002011-04-04T17:47:29.612-07:00SPIN is a W3C Member SubmissionThe SPARQL Rules language <a href="http://spinrdf.org/"><b>SPIN</b></a> has evolved over the last couple of years as an integral part of TopQuadrant's TopBraid Suite. SPIN started during a discussion between Dean Allemang and myself, in which we brainstormed about having an RDF syntax for SPARQL. I went ahead and implemented this based on Jena's ARQ API, and the result eventually became the <a href="http://www.w3.org/Submission/spin-sparql/">SPIN RDF Syntax</a>. This was no rocket science, because similar ideas of representing higher level languages by means of RDF blank node structures had been explored by OWL and SWRL.<div><br /></div><div>Prior to our work on SPIN, we had already experimented with various mechanisms to link SPARQL queries with RDF data structures, so that they could be shared as query libraries. TopBraid veterans may remember the sparql:query property that was introduced to store SPARQL queries (as strings) together with RDF models. So while I was working on the SPIN RDF Syntax, I noticed that we now have a much better way of achieving this goal. A quick cross-reference to object-oriented languages led to me select properties such as spin:rule and spin:constraint to point from a class to a SPARQL query, expressed in RDF. This later became the <a href="http://www.w3.org/Submission/spin-modeling/">SPIN Modeling Vocabulary</a>.</div><div><br /></div><div>Once I had the rules and constraint mechanism in place, I noticed that many rules and constraints were following similar patterns, with just one or two values different in each rule. This led to the creation of <a href="http://composing-the-semantic-web.blogspot.com/2009/01/understanding-spin-templates.html">SPIN Templates</a>. Templates then became the foundation of user-defined <a href="http://composing-the-semantic-web.blogspot.com/2009/01/understanding-spin-functions.html">SPIN Functions</a>. With those two pieces in place, SPIN suddenly became a language that was fundamentally different (and better) than what similar languages such as SWRL provided, because it became possible for users to define their own modeling vocabulary, and even extend the expressivity of SPARQL.</div><div><br /></div><div>The first version of SPIN was <a href="http://composing-the-semantic-web.blogspot.com/2009/01/introducing-spin-sparql-inferencing.html">published</a> as part of TopBraid Composer in January 2009. Since then, it was positively received by our user community and practical use cases have enabled us to fine tune and extend the language over the years. Now, around three years after its first experimental versions, we found the time was right to officially share SPIN with the broader community, and make clear that it is not a proprietary TopQuadrant technology. Together with James Hendler and Kingsley Idehen, we put together a <a href="http://www.w3.org/Submission/spin-overview/">SPIN W3C Member Submission</a> that has just been published on the W3C site.</div><div><br /></div><div>The status of a Member Submission means that TopQuadrant encourages other tool vendors to also provide SPIN implementations, and as I have heard there is work in progress already. The Member Submission also indicates that SPIN <a href="http://www.w3.org/Submission/2011/02/Comment/">may</a> play a role as input to future revisions of other standards such as RIF. This is all very good. Of course a full spec of SPIN as an official W3C standard would be even better, but going through the whole standardization process is a long and difficult journey. Given that SWRL had become a similar de-facto standard with Member Submission status alone indicates to me that SPIN has good chances of achieving the same. In fact I strongly believe that the fact that SPIN is based on SPARQL will be crucial in winning the hearts and minds of many Semantic Web and Linked Data enthusiasts. SPIN can co-exist with other languages including <a href="http://composing-the-semantic-web.blogspot.com/2009/01/owl-2-rl-in-sparql-using-spin.html">OWL 2 RL</a> and <a href="http://topquadrantblog.blogspot.com/2010/08/how-to-find-skos-constraint-violations.html">SKOS</a>. SPIN doesn't require any special execution engine apart from a SPARQL store. The learning curve is very low for anyone who already knows SPARQL. SPIN is part of the Semantic Web technology stack.</div><div><br /></div><div>A good place to start learning SPIN is the <a href="http://www.topquadrant.com/products/SPIN.html"><b>TopBraid SPIN</b></a> page, with screenshots and links to a tutorial. For programmers, there is an <a href="http://topbraid.org/spin/api/">open source SPIN API</a> available.</div>Holger Knublauchhttp://www.blogger.com/profile/13180242480924209321noreply@blogger.com0tag:blogger.com,1999:blog-31416365.post-23813570111287063182011-01-25T17:36:00.000-08:002012-07-03T17:41:26.658-07:00A Textual Syntax for SPARQLMotion<p><b>UPDATE (2012-07-04): TopBraid 3.6.1 is the last version supporting this syntax. It is now possible to embed SPARQLMotion scripts into SWP documents, and this provides very similar capabilities (and more).</b></p>
<a href="http://sparqlmotion.org/">SPARQLMotion</a> is an RDF-based scripting language that is suitable to be presented and edited graphically to form data processing pipelines. Many of our customers are using SPARQLMotion and we are constantly extending and refining the tools to make it more powerful. One of the recent enhancements that made it into TopBraid 3.4 is support for an alternative textual notation for SPARQLMotion. A spec for this notation can be found here:<div><br /></div><div style="text-align: center;"><a href="http://sparqlmotion.org/smXMLSyntax.html"><b>http://sparqlmotion.org/smXMLSyntax.html</b></a></div><div><br /></div><div>An example of how this XML-based notation for SPARQLMotion can be used is shown in the TopBraid Composer screenshot's sm:bodyScript field below.</div><div><br /></div><div><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVcXlrd8cAFxNyTNd2Eucl7vBYm_qyiKV6zJtPS4HeM_oGU1dTMqd2GVJ3i4qikyZRn_i5HG8E-Lyc-igk49CUQZAnq0sDP1iV3kgYK6q1tDophGJ2Oe9krCVwsVHlPqLdTrSG7w/s1600/SM-XML-Example.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 369px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVcXlrd8cAFxNyTNd2Eucl7vBYm_qyiKV6zJtPS4HeM_oGU1dTMqd2GVJ3i4qikyZRn_i5HG8E-Lyc-igk49CUQZAnq0sDP1iV3kgYK6q1tDophGJ2Oe9krCVwsVHlPqLdTrSG7w/s400/SM-XML-Example.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5566304658308470018" /></a></div><div>The script above is stored in the same RDF-based format like other SPARQLMotion scripts, and can still be visualized graphically:</div><div><br /></div><div><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiz0KDjKkpOtyzfpdadJXfPrU5ZV4t0M_M6vJn_3PxJZDsoby1NGo68MJ8YGYO6U1JrlZtU8tPZnS_5WLLRkTmJMxqQWLMVFd54HB2TtBtXx61RsQ5ps8vcAiUyTdJJ0uD-b_bXQA/s1600/SM-Graph-Example.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 300px; height: 282px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiz0KDjKkpOtyzfpdadJXfPrU5ZV4t0M_M6vJn_3PxJZDsoby1NGo68MJ8YGYO6U1JrlZtU8tPZnS_5WLLRkTmJMxqQWLMVFd54HB2TtBtXx61RsQ5ps8vcAiUyTdJJ0uD-b_bXQA/s400/SM-Graph-Example.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5566306414194771170" /></a></div><div>In the past few years since SPARQLMotion was created, several people had asked about a notation that can be edited with conventional text editing tools to create scripts. Among the advantages of a text-based notation is that it becomes easier to perform large-scale refactorings to move things around. It is sometimes simply faster, plus there is no need to "invent" artificial URIs for the nodes in a script. A great plus of the XML-based notation is that it becomes easy to insert <a href="http://uispin.org/">SPARQL Web Pages</a> (aka UISPIN) snippets directly into a single document. This can significantly accelerate the development of SPARQL-based web services.</div><div><br /></div><div>The XML notation does have various limitations though. In particular it is only suitable for a subset of SPARQLMotion - there is no concept of multiple predecessor nodes in a linear notation.</div>Holger Knublauchhttp://www.blogger.com/profile/13180242480924209321noreply@blogger.com0tag:blogger.com,1999:blog-31416365.post-47104310280126315072011-01-10T18:59:00.000-08:002011-01-10T19:18:41.350-08:00Understanding SPARQL Rules with the SPIN Statistics View<div>One of the new features of <a href="http://www.topquadrant.com/products/TB_Composer.html">TopBraid Composer</a> 3.4 is a new view called SPIN Statistics. Whenever this view is open and you run some <a href="http://spinrdf.org/">SPARQL Rules</a>, this will record the execution time of each individual rule. When completed, you can browse the performance characteristics of each rule, grouped by invocations or by the associated class. In the following screenshot, the <a href="http://topbraid.org/spin/owlrl-all.html">SPIN rules for OWL 2 RL</a> executed over the pizza ontology are recorded:</div><div><br /></div><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6-0wBWfCqPslQSQuvyEGtKM6SP-TzaRd-wVl6tCCqYdGjQ2E-tCyYn3jdH7IJC_66jxIDGGyrtiod7bEcQLA1OIe-uFw8rB9BBKUtTnmzmr12nlMAh6alTdma9CBZcV462vfucw/s1600/TBC-SPIN-Statistics-OWL2RL.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 114px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6-0wBWfCqPslQSQuvyEGtKM6SP-TzaRd-wVl6tCCqYdGjQ2E-tCyYn3jdH7IJC_66jxIDGGyrtiod7bEcQLA1OIe-uFw8rB9BBKUtTnmzmr12nlMAh6alTdma9CBZcV462vfucw/s400/TBC-SPIN-Statistics-OWL2RL.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5560758903885105954" /></a>According to the statistics in this screenshot, the rule that implements the transitivity of rdfs:subClassOf has taken the largest fraction of the time. This can help identify performance bottlenecks, and may also be useful to understand better what happens inside of the rule engine. The view can be filled incrementally, e.g. to accumulate how certain rules fire over different data sets.<br /><div><br /></div>Holger Knublauchhttp://www.blogger.com/profile/13180242480924209321noreply@blogger.com0tag:blogger.com,1999:blog-31416365.post-29893332238018766082010-12-13T17:44:00.000-08:002010-12-13T19:22:47.844-08:00The Teamwork OntologyThe newly released <a href="http://topquadrant.com/products/release_notes/v3_4_0.html">TopBraid Suite 3.4</a> introduces the <a href="http://www.topquadrant.com/solutions/ent_vocab_net.html">Enterprise Vocabulary Net (EVN)</a>, an out-of-the-box solution for web-based development and management of interconnected controlled vocabularies. The focus of this product for now is on collaborative editing of SKOS models, and the EVN link above will lead you to screenshots showing this in action. I should write a couple of blog entries about this, but here is one about one particular aspect of the EVN system - its support for keeping track of changes (on the SKOS models) in a multi-user environment.<div><br /></div><div>The requirements of EVN include the ability of teams to collaborate on edits on an enterprise vocabulary. Imagine a media company wants to build a semantic web model of concepts that are relevant in its domain. This media company would have domain experts on the "news" channel, and for this news channel, a controlled vocabulary would be needed to be able to categorize incoming news items so that they can be processed more easily down the road. A simple SKOS hierarchy would define standard identifiers (URIs) for things like Sports, and under that there would be sub-concepts such as RacquetSports, with further specializations including Tennis and Badminton.</div><div><br /></div><div>In order to build such a controlled vocabulary, the media company would create a team of domain experts, and each group of experts would collaborate independently to fill in the various sub-trees of the overall enterprise vocabulary. In the TopBraid EVN system, this is implemented through an editing process in which different people can play different roles. Assume the sports experts want to add another bunch of categories to classify the various kinds of football, then they would open a so-called "working copy". The working copy is a logical extension of the master model, but also includes local changes that are not yet visible to the rest of the team. The sports team can experiment with arbitrary edits in their working copy sandbox. When done, they can change the status of their working copy to trigger a review process. At this stage, no further edits will be done, until a reviewer (who "owns" the master copy) had a chance to OK or reject those edits. If OK, the working copy will be retired, and all changes will be applied to the master copy and thus published to the rest of the enterprise. If rejected, the sports people may want to make additional edits.</div><div><br /></div><div>In order to support such workflows, we have designed an RDF based framework for tracking and managing changes on RDF models. This framework, internally called "teamworks support" is based on the teamwork ontology (<a href="http://topbraid.org/teamwork">http://topbraid.org/teamwork</a>), an excerpt of which is outlined in the class diagram below, together with some technical details.</div><div><br /></div><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXiYWBQfNMYh5mr7yRoquNns37CRqHN8xoA0j2a7oLoLRBKr2_0_VQgE_K_rVUseGLtihY8bakS2_pAV_u4VcD1aCEJFJ44TftgcAao_gNLavHicWrRxdN-fVtld5SHmCamlLhog/s1600/teamwork-class-diagram.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 268px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXiYWBQfNMYh5mr7yRoquNns37CRqHN8xoA0j2a7oLoLRBKr2_0_VQgE_K_rVUseGLtihY8bakS2_pAV_u4VcD1aCEJFJ44TftgcAao_gNLavHicWrRxdN-fVtld5SHmCamlLhog/s400/teamwork-class-diagram.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5550354467434927298" /></a>The teamwork ontology represents changes (teamwork:Change) made by users (sioc:UserAccount) on governed resources. The governed resources are either a whole model (the master copy, an instance of owl:Ontology), or working copies (teamwork:Tag). If a group of users wants to add a new category of sports concepts, then it would create a teamwork:Tag and give it a label such as "Add football sports". This will become the container of any number of smaller changes, each represented as instances of teamwork:Change, which are recorded together with a time stamp and creator. Each Change points to one or more added or deleted RDF triples, where the triples are stored as reified statements of the class teamwork:Statement. A Change can be associated with a working copy (teamwork:Tag) via the property teamwork:tag. The collection of Change objects associated to a Tag form a group of edits that can be tracked in the workflow using the property teamwork:status at the teamwork:Tag. Example status values are teamwork:Uncommitted, teamwork:FrozenForReview and teamwork:Rejected.<br /><div><br /></div><div>The teamwork user model manages user accounts as well as the roles that each user can play within a working copy and the master vocabulary. This is done through the sub-properties of teamwork:role: viewer (read-only), editor (write access) and manager (write access and workflow control).</div><div><br /></div><div>The teamwork triples above are stored in separate graphs, called the teamwork graphs, that are linked to the edited vocabularies via a file ending with .tch.*. For example, the graph example.tdb may have a companion graph stored in example.tch.tdb. As soon as TopBraid finds a .tch file with a matching name, it will put the ontology under teamwork control, which means that changes will be automatically tracked whenever someone writes the the graph. Furthermore, all graphs under teamwork control will show up on the log in page of the EVN application. The following figure illustrates this set up:</div><div><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoqaHPrGyTeBdHk3LGVQ94ti8rcVgEo8BQNI_SRouS602AFK-i3ZTe8QZWxOSDdWRWEA3NwvjwoHN0x9ytCUKH-0wdWmNccWEFO97MLUE2Y6JQnDUVkhNnc1a4WZ7joLaDFwyGkw/s1600/teamwork-architecture.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 344px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoqaHPrGyTeBdHk3LGVQ94ti8rcVgEo8BQNI_SRouS602AFK-i3ZTe8QZWxOSDdWRWEA3NwvjwoHN0x9ytCUKH-0wdWmNccWEFO97MLUE2Y6JQnDUVkhNnc1a4WZ7joLaDFwyGkw/s400/teamwork-architecture.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5550368101571617250" /></a></div><div>The teamwork graph will contain any metadata about the changes, i.e. any teamwork:Change objects, the reified triples, information about the working copies etc. It may easily become larger than the actual main model, because it can keep track of the whole audit trail, and may use four triples for each changed triple. When a user logs into a working copy, the system creates a logical view - a graph that does not necessarily have a physical representation, but may be populated on demand. When created, this logical view will check the teamwork database for any uncommitted changes associated with the given working copy. Those changes will then be visible to the editing user, without having to be materialized in the actual master copy database. When the user makes some edits, the changes will only be logged into the teamwork database. Changes only make it into the master database, if the manager approves them. From that moment on, they will become automatically visible to any existing logical view.</div><div><br /></div><div>There is much more to say about this whole architecture, but I'll leave these details for later. It suffices to say that the user interfaces of EVN and TopBraid Composer will shield the user from all those details. But if you ever want to get low level access to those teamwork repositories yourself, you can easily do that: just open the .tch files in TopBraid Composer and browse the content. If you have made some edits from EVN, you can see which triples are impacted in the teamwork graph. You can use SPARQL to query the changes, e.g. to find all changes that mention a given resource, or all changes within a certain time interval. You can also use scripting languages like SPARQLMotion to perform batch operations on the teamwork repositories.</div><div><br /></div><div>The fact that we are using RDF all the way down makes the TopBraid teamwork support a very transparent and consistent architecture for change management.</div>Holger Knublauchhttp://www.blogger.com/profile/13180242480924209321noreply@blogger.com0tag:blogger.com,1999:blog-31416365.post-87496805756595265442010-11-28T15:03:00.000-08:002010-11-28T15:09:38.874-08:00UISPIN is now SPARQL Web PagesAs part of the official release of UISPIN 1.0 with TopBraid Suite 3.4, we have decided to give it a more compelling and more descriptive name: <a href="http://uispin.org">SPARQL Web Pages (SWP)</a>. There are no technical implications of the new name - it's mostly to communicate better what this technology is all about: Creating HTML (and XML) documents by embedding SPARQL expressions and queries into template documents. The namespaces and many of the technical references will continue to use the term UISPIN, which illustrates the lower-level technical aspect (of being the User Interface layer of the <a href="http://spinrdf.org">SPIN</a> framework).Holger Knublauchhttp://www.blogger.com/profile/13180242480924209321noreply@blogger.com0