<docbook><section><title>VirtLinkedDataDeployment</title><para>  </para>
<title> Deploying Linked Data</title> Deploying Linked Data
<para>v1.2 (Virtuoso 5.0) April 2008</para>
<para>This document describes the process of deploying Linked Data into the existing Web.
 It discusses some of the difficulties faced in exposing RDF data and in bridging the &quot;Semantic Data-Web&quot; and the traditional &quot;Document Web&quot;.
 Two generic approaches to resolving these deployment challenges are described, content negotiation and URL rewriting, before looking at <ulink url="OpenLink">OpenLink</ulink> Virtuoso, both from the standpoint of how it implements these solutions and how Linked Data is deployed.</para>
<para>A companion document, <ulink url="RDFViewOverviewDoc">Virtuoso Linked Data Views Getting Started Guide</ulink>, focuses on Virtuoso Linked Data Views, a facility for exposing relational data as RDF.
 In addition, it provides useful background information for readers unfamiliar with RDF and outlines some of the key technologies of the Semantic Web.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h2"> Introduction</bridgehead>
<para>The ubiquitous &quot;Web,&quot; born as the &quot;World Wide Web,&quot; is primarily experienced today as a &quot;Web of <emphasis>Documents</emphasis>,&quot; where documents (or Web pages) are connected by simple hypertext links.
 When you click on a hypertext link within one document, the result is simply that the browser loads (or downloads) the linked document.
 This widely understood and accepted pattern of interaction with the Web is made possible by two things — the <emphasis>Uniform Resource Identifier</emphasis>, or <emphasis>URI</emphasis>, and the <emphasis>Hypertext Transfer Protocol</emphasis>, or <emphasis>HTTP</emphasis>.</para>
<para>(Uniform Resource <emphasis>Identifier?</emphasis>  <emphasis>URI?</emphasis>  Don&#39;t we mean <emphasis>URL</emphasis>, or Uniform Resource <emphasis>Locator</emphasis>?  Yes and no.
 A Uniform Resource <emphasis>Locator</emphasis> (URL) is a particular kind of Uniform Resource <emphasis>Identifier;</emphasis> a Uniform Resource <emphasis>Name</emphasis>, or URN, is another.
 As may be obvious from these names, a <emphasis>URL</emphasis> specifies the <emphasis>location</emphasis> of a resource -- like, &quot;the piece of paper centered on the blotter on your desk,&quot; or &quot;the third book from the left on the top shelf of the bookcase in the entryway.&quot;  A <emphasis>URN</emphasis> specifies the <emphasis>name</emphasis> of a resource -- like &quot;your resume,&quot; or &quot;the local Chicago telephone directory.&quot;  Both of these are <emphasis>URIs</emphasis> -- as both can be used to <emphasis>identify</emphasis> the resource in question, at a given moment in time.
 The piece of paper centered on the blotter on your desk, and where the book is shelved, may change -- and though the URL is the same as what once referred to your resume, the URN is now different, as it is now &quot;the menu for the pizza place down the street,&quot; or &quot;the Tom Robbins novel, <emphasis>Still Life With Woodpecker</emphasis>.&quot;  On the Web, URLs can only lead to HTTP-transmissible documents, so the paper on which your resume is printed cannot actually have a URL -- but the word processing document which was printed on that paper <emphasis>can</emphasis> have a URL.
 In this example, both the word processing document and the printout are associated with the URN, &quot;your resume,&quot; and each is a different <emphasis>representation</emphasis> thereof -- one which is only easily consumable by humans, and one which is easily consumable by humans or machines.
 URNs are typically less transient, as &quot;your resume&quot; will always mean the same document, but that document&#39;s content will change over time -- so increasingly common practice is to have URNs that incorporate some sense of time into the name, often leading to two &quot;special&quot; URNs which are tied to the &quot;first&quot; and the &quot;latest&quot; version of the document.
 The &quot;first&quot; always leads to the same content -- but the &quot;latest&quot; is obviously likely to change over time.)</para>
<para>The popularity of the current &quot;Document Web&quot; sometimes obscures the fact that from the onset, Tim Berners-Lee envisaged a broader and deeper Web of <emphasis>Linked Data</emphasis>, where URIs weren&#39;t simply URLs and therefor limited to association with HTTP-transmissible documents, and where links between resources were not limited to simple hypertext.
 URNs make it possible to have &quot;hyperdata&quot; links — explicit connections between <emphasis>Named Entities</emphasis> or <emphasis>Data Objects</emphasis>, rather than vague connections between document locations.
 Hyperdata links include descriptions of the kind of link exposed — such as &quot;the PDF representation of your resume,&quot; &quot;the Microsoft Word representation of your resume,&quot; &quot;the website of the company at which you worked in 1998 which was named Widgets, Inc.&quot;  There is no natural requirement that URNs be based on HTTP, but as we discuss below this <emphasis>is</emphasis> necessary to enabling the Web of Linked Data.</para>
<para>This document describes one way to start sprinkling Linked Data into the existing Document Web, gradually bringing the Web closer to Tim Berners-Lee&#39;s vision, without breaking its current functionality.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h3"> What is Linked Data?</bridgehead>
<para>&quot;Linked Data&quot; is the title of a Web Design Issues Note by Berners-Lee that issues a best practice recipe for injecting data into the Web as part of a broader effort to evolve the current Web of interlinked documents to a Web of interlinked data known as the &quot;Semantic Data-Web&quot; (Data-Web).
 The principles he outlined are paraphrased as:</para>
<itemizedlist mark="bullet" spacing="compact"><listitem>Identify things (real or abstract) in your universe-of-discourse (or &quot;data space&quot;) using URIs (whether URNs or URLs — each has its place) </listitem>
<listitem>Make each URI (URN, URL, or otherwise) acessible via HTTP, so that people can discover and explore your data spaces via the Web </listitem>
<listitem>Use URIs to expose the context of your data (i.e., describe and provide other information about your data, using URIs) </listitem>
<listitem>Enhance your URIs by adding links to other URIs, enabling discovery of other things on the Web</listitem>
</itemizedlist><bridgehead class="http://www.w3.org/1999/xhtml:h3"> Deployment Challenges</bridgehead>
<para>The Data-Web and the Document Web are two dimensions of the same Web separated by a common element: the URI.
 On the Document Web, URIs always point to physical resources, while in the Data-Web they point to physical things that are associated with physical and/or abstract things.
 Of course, this unveils a number of deployment challenges.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h3"> Data Object Names</bridgehead>
<para>In the current Document Web, resource URIs do not separate <emphasis>identity</emphasis> from <emphasis>representation</emphasis>.
 The Document Web assumes that a resource URI points to the location of a physical Web information resource.
 The HTTP payload that conveys the &quot;GET&quot; request for a resource also includes a mechanism for defining representation.
 Thus, the URI <ulink url="http://demo.openlinksw.com/Northwind/Customer/ALFKI">http://demo.openlinksw.com/Northwind/Customer/ALFKI</ulink> points to the (X)HTML document representation of the physical resource ALFKI located in the directory /Northwind/Customer/ on host machine demo.openlinksw.com that accepts HTTP requests at the default port 80.</para>
<para>The Data-web on the other hand, seeks to use the URI scheme in a manner that separates identity from representation.
 A URI may simply identify a physical or abstract entity, aka a &quot;data object&quot;, and so serve as a unique data object name or ID.
 Accessing, or de-referencing, the data object returns a representation of the object, not the object itself.
 (For instance, the object in question may be Paris!)</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h4"> Unambiguous Reference vs Ambiguous Access</bridgehead>
<para>When we refer to, or identify, a data object through a data object name, that reference should be unambiguous.
 However, when we access (or de-reference) a data object, access is inherently ambiguous.
 Accessing an abstract data object relies on materialization of a description of the entity in a form compatible with the transmission medium.
 As the object may have many possible descriptions (facets), the act of accessing it is ambiguous.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h4">URIs As Unique Data Object Names</bridgehead>
<para>Thus, unlike in the Document Web, in the Semantic Web the same URI <ulink url="http://demo.openlinksw.com/Northwind/Customer/ALFKI">http://demo.openlinksw.com/Northwind/Customer/ALFKI</ulink> cannot serve as both the identity and representation of the Customer ALFKI.
 The Linked Data provider needs to adhere to a URI based naming convention in order to avoid data access ambiguity.
 For example, the URI <ulink url="http://demo.openlinksw.com/Northwind/Customer/ALFKI#this">http://demo.openlinksw.com/Northwind/Customer/ALFKI#this</ulink>, could always to taken to imply the ID of the Customer data object referred to as ?ALFKI?.
 The URI with the #this suffix is a so-called <emphasis>hash URI</emphasis>, which is a convention adopted by some practitioners.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h3">Difficulties with Hash URIs As Data Object Names</bridgehead>
<para>In the prior section, we established the need for disambiguating references and accesses to resources via the Data-Web, and highlighted the <emphasis>hash URI</emphasis> scheme as one scheme some practitioners have adopted when using URIs as unique data object names.
 However from the perspective of the Data-Web Server (the piece responsible for understanding Reference), the URIs <ulink url="http://demo.openlinksw.com/Northwind/Customer/ALFKI">http://demo.openlinksw.com/Northwind/Customer/ALFKI</ulink> and <ulink url="http://demo.openlinksw.com/Northwind/Customer/ALFKI#this">http://demo.openlinksw.com/Northwind/Customer/ALFKI#this</ulink> are identical, and thereby inherently ambiguous, because nothing following the fragment identifier, &quot;#&quot;, ever leaves the Web Client, due to the fact that the Web Client expects to process &quot;#this&quot; locally, post resource retrieval.
As a result, the Data-Web Server has to figure out how to dereference the Information Resource URI <ulink url="http://demo.openlinksw.com/Northwind/Customer/ALFKI">http://demo.openlinksw.com/Northwind/Customer/ALFKI</ulink> and the Identity URI <ulink url="http://demo.openlinksw.com/Northwind/Customer/ALFKI#this">http://demo.openlinksw.com/Northwind/Customer/ALFKI#this</ulink> from the HTTP GET request payload that will only predictably contain the URI <ulink url="http://demo.openlinksw.com/Northwind/Customer/ALFKI">http://demo.openlinksw.com/Northwind/Customer/ALFKI</ulink>.
 (Even if a Web client knowingly tacks the data following the &quot;#&quot; to the HTTP GET request it has no control over proxies along the way that may strip out &quot;#this&quot;.) Likewise, referencing an entity via its identity URI (the act of dereferencing) is only achieved via interaction with an associated Web information resource that &quot;DESCRIBE&quot; the entities in question.
 In reality, this associative process is inherently ambiguous and unavoidable.</para>
<para>It is also important to note that descriptive Web information resources can take the form of bona fide parameterized URLs of the kind commonly associated with RESTful Web Services.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h3"> Resolution of the Deployment Challenge</bridgehead>
<para>To unobtrusively evolve the dominant Document Web usage pattern to a Data-Web usage pattern, the challenges of Data Access and Data Reference need to be resolved using the existing Web infrastructure.
 The best means of resolution is content negotiation as it provides the foundation for an unobtrusive mechanism known as URL rewriting.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h3"> Content Negotiation</bridgehead>
<para>Content negotiation is a mechanism defined in the HTTP specification that makes it possible to serve different representations of <ulink url="">
 a document (or any resource) at the same (<ulink url="#FootNote1">Note 1</ulink>) URL, so that software agents can choose which representation best fits their capabilities.
The originally conceived need for this mechanism stemmed from mobile phone browsers, which were better suited to smaller page sizes, without many graphics and other niceties of the fully featured Web, often satisfied by a WAP representation.
 In the world of RDF, a user interacting through a traditional Web browser may want a resource represented in HTML or XHTML, whereas a Semantic Web application would prefer an RDF/XML representation due to its Structured Data orientation.</ulink></para>
<para>A browser or any other HTTP based web application indicates it resource representation preferences by packaging these preferences via the &quot;Accept:&quot; headers of each HTTP request.
 For example, a browser could send this HTTP request to indicate that it wants an HTML or XHTML version of <ulink url="http://www.openlinksw.com/whitepapers/data_management">http://www.openlinksw.com/whitepapers/data_management</ulink> in English or French:</para>
<programlisting>GET /whitepapers/data_management HTTP/1.1 
Host: www.openlinksw.com 
Accept: text/html, application/xhtml+xml 
Accept-Language: en, fr 
</programlisting><para> Here, the HTTP Accept header sent by the browser indicates the MIME types it wants (text/html or application/xhtml+xml).
 An RDF browser, in contrast, might stipulate a MIME type of application/rdf+xml or application/rdf+n3 to receive a rendering in RDF/XML or N3 respectively.</para>
<para>Rather than returning the content in the required format directly, servers often implement content negotiation by redirecting to a URL where the appropriate representation is found.
 For example, a server might respond with:</para>
<programlisting>HTTP/1.1 302 Found 
Location: http://www.openlinksw.com/whitepapers/data_management.en.html
</programlisting><para> The redirect is indicated by the HTTP status code 302 (Found).
 The client would then send another HTTP request to the new URL.
HTTP defines a number of 3xx status codes all of which indicate the client is being redirected.
 Instead of 302, servers can also use 303 (See Other) to indicate the response to the request can be found at another location (as expressed via the &quot;Location:&quot; response header).</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h4"> HttpRange - 14 Recommendations</bridgehead>
<para>The problem of URI/resource-type interpretation was originally addressed by the W3C Technical Architecture Group (TAG) around 2005 and was known as the &quot;<ulink url="HttpRange">HttpRange</ulink>-14&quot; issue.
 After a good deal of deliberation, the TAG proposed the guidelines below on the information that can be inferred from the HTTP protocol response codes when dereferencing a URI:</para>

<table><title /><tgroup><thead /><tbody>
<row />
<row><entry>200 (success)</entry><entry>A Resource Representation and its Location</entry><entry>A Web information resource has been located in the desired Representation.</entry></row>
<row><entry>303 (see other)</entry><entry>A Resource Location</entry><entry>A redirection to the Location of an associated Web information resource in a desired Representation.</entry></row>
<row><entry>4XX or 5XX  (error)</entry><entry>Nothing</entry><entry>No Web information resource or Resource Location is discernible from the Resource and Representation combination used in the message.</entry></row>
</tbody></tgroup></table>
<bridgehead class="http://www.w3.org/1999/xhtml:h4"> Solving Linked Data Challenges using Content Negotiation</bridgehead>
<para>Returning to our earlier example URIs (<ulink url="http://demo.openlinksw.com/Northwind/Customer/ALFKI">http://demo.openlinksw.com/Northwind/Customer/ALFKI</ulink> and <ulink url="http://demo.openlinksw.com/Northwind/Customer/ALFKI#this">http://demo.openlinksw.com/Northwind/Customer/ALFKI#this</ulink>) we can construct a decision table that demonstrates how a deployer of Linked Data would leverage content negotiation en route to alleviating the previously outlined Data Access and Data Reference challenges.</para>

<table><title /><tgroup><thead /><tbody>
<row />
<row><entry><ulink url="http://demo.openlinksw.com/Northwind/Customer/ALFKI">http://demo.openlinksw.com/Northwind/Customer/ALFKI</ulink> </entry><entry> Slash based </entry><entry> 406 (Not available or applicable) or 303 (Redirect to an associated resource in requested representation format, e.g., <ulink url="http://demo.openlinksw.com/">http://demo.openlinksw.com/</ulink>)</entry><entry> 303 (Redirect to URL of information resource that DESCRIBEs the entity <ulink url="http://demo.openlinksw.com/">http://demo.openlinksw.com/</ulink> in the Data space <ulink url="http://demo.openlinksw.com/">http://demo.openlinksw.com/</ulink>) </entry></row>
<row><entry><ulink url="http://demo.openlinksw.com/Northwind/Customer/ALFKI#this">http://demo.openlinksw.com/Northwind/Customer/ALFKI#this</ulink> </entry><entry> Hash based </entry><entry> 200 OK (Since fragment ID component of the URI doesn&#39;t affect the URL for the information resource </entry><entry> 200 OK (Return an information resource that DESCRIBEs the entity <ulink url="http://demo.openlinksw.com/">http://demo.openlinksw.com/</ulink> </entry></row>
</tbody></tgroup></table>
<bridgehead class="http://www.w3.org/1999/xhtml:h3"> URL Rewriting</bridgehead>
<para>URL rewriting is the act of modifying a source URL prior to the final processing of that URL by a Web Server.</para>
<para>The ability to rewrite URLs may be desirable for many reasons that include:</para>
<itemizedlist mark="bullet" spacing="compact"><listitem>Changing Web information resource URLs on the a Web Server without breaking existing bookmarks held in User Agents (e.g., Web browsers)</listitem>
</itemizedlist><itemizedlist mark="bullet" spacing="compact"><listitem>URL compaction where shorter URLs may be constructed on a conditional basis for specific User Agents (e.g., Email clients)</listitem>
</itemizedlist><itemizedlist mark="bullet" spacing="compact"><listitem>Construction of search engine friendly URLs that enable richer indexing since most search engines cannot process parameterized URLs effectively.</listitem>
</itemizedlist><bridgehead class="http://www.w3.org/1999/xhtml:h4"> Using URL Rewriting to Solve Linked Data Deployment Challenges</bridgehead>
<para>In the previous section we demonstrated how content negotiation and HTTP response messages could be used to address the data access issues arising from the use of URIs associated with resource identity and representation.</para>
<para>We determined earlier that URI naming schemes don&#39;t resolve the challenges associated with referencing data.
To reiterate, this is demonstrated by the fact that the URIs <ulink url="http://demo.openlinksw.com/Northwind/Customer/ALFKI">http://demo.openlinksw.com/Northwind/Customer/ALFKI</ulink> and <ulink url="http://demo.openlinksw.com/Northwind/Customer/ALFKI#this">http://demo.openlinksw.com/Northwind/Customer/ALFKI#this</ulink> both appear as <ulink url="http://demo.openlinksw.com/Northwind/Customer/ALFKI">http://demo.openlinksw.com/Northwind/Customer/ALFKI</ulink> to the Web Server, since data following the fragment identifier &quot;#&quot; never makes it that far.</para>
<para>The only way to address data referencing is by pre-processing source URIs (e.g., via regular expression or sprintf substitutions) as part of a URL rewriting processing pipeline.
 The pipeline process has to take the form of a set of rules that cater for elements such as HTTP Accept headers, HTTP response code, HTTP response headers, and rule processing order.</para>
<para>An example of such a pipeline for the hash URI scheme is depicted in the table below:</para>

<table><title /><tgroup><thead /><tbody>
<row />
<row><entry>/Northwind/Customer/([^#]*)</entry><entry>None (meaning default)</entry><entry>200 or 303 responses depending on the user agent default or server side quality of service rules via Transparent Content Negotiation.</entry><entry>None</entry><entry>Normal (order irrelevant)</entry></row>
<row><entry>/Northwind/Customer/([^#]*)</entry><entry>(text/rdf.n3) / (application/rdf.xml) </entry><entry> 200 OK and return the information resource that DESCRIBEs the entity identified by the hash URI in the requested representation. </entry><entry> None </entry><entry> Normal (order irrelevant) </entry></row>
<row><entry>/Northwind/Customer/([^#]*)</entry><entry> (text/html) / (application/xhtml.xml) </entry><entry> 200 OK and return an information resource in requested representation. </entry><entry> None </entry><entry> Normal (order irrelevant) </entry></row>
</tbody></tgroup></table>
<para>A similar pipeline for the slash URI scheme would be:</para>

<table><title /><tgroup><thead /><tbody>
<row />
<row><entry>/Northwind/Customer/([^#]*)</entry><entry>None (meaning default)</entry><entry>200 or 303 responses depending on the user agent default or server side quality of service rules via Transparent Content Negotiation.</entry><entry> None </entry><entry> Normal (order irrelevant) </entry></row>
<row><entry>/Northwind/Customer/([^#]*)</entry><entry>(text/rdf.n3) / (application/rdf.xml)</entry><entry> 303 Redirect to an associated URL of an information resource that DESCRIBEs the entity identified by the URI </entry><entry> None</entry><entry>Normal (order irrelevant)</entry></row>
<row><entry>/Northwind/Customer/([^#]*)</entry><entry>(text/html) / (application/xhtml.xml)</entry><entry>406 (Not Acceptable) or 303 Redirect to location of resource in requested representation</entry><entry>Vary: negotiate, accept Alternates: {&quot;ALFKI&quot; 0.9 {type application/rdf+xml}}</entry><entry>Last (must be last in processing chain)</entry></row>
</tbody></tgroup></table>
<para>The source URI patterns refer to virtual or physical directories at <ulink url="http://demo.openlinksw.com/">http://demo.openlinksw.com/</ulink>.
 Rules can be placed at the head or tail of the pipeline, or applied in the order they are declared, by specifying a Rule Processing Order of First, Last, or Normal, respectively.
 The decision as to which representation to return for URI <ulink url="http://demo.openlinksw.com/Northwind/Customer/ALFKI">http://demo.openlinksw.com/Northwind/Customer/ALFKI</ulink> is based on the MIME type(s) specified in any Accept header accompanying the request.</para>
<para>In the case of the last rule, the Alternates response header applies only to response code 406.
 406 would be returned if there were no (X)HTML representation available for the requested resource.
 In the example shown, an alternative representation is available in RDF/XML.</para>
<para>When applied to matching HTTP requests, the last two rules might generate responses similar to those below:</para>
<programlisting>
$ curl -I -H &quot;Accept: application/rdf+xml&quot; http://demo.openlinksw.com/Northwind/Customer/ALFKI

HTTP/1.1 303 See Other
Server: Virtuoso/05.00.3016 (Solaris) x86_64-sun-solaris2.10-64 PHP5
Connection: close
Content-Type: text/html; charset=ISO-8859-1
Date: Mon, 16 Jul 2007 22:40:03 GMT
Accept-Ranges: bytes
Location: /sparql?query=CONSTRUCT+{+%3Chttp%3A//demo.openlinksw.com/Northwind/Custom
er/ALFKI%23this%3E+%3Fp+%3Fo+}+FROM+%3Chttp%3A//demo.openlinksw.com/Northwind%3E+WHE
RE+{+%3Chttp%3A//demo.openlinksw.com/Northwind/Customer/ALFKI%23this%3E+%3Fp+%3Fo+}&amp;
format=application/rdf%2Bxml
Content-Length: 0 
</programlisting><para> In the cURL exchange depicted above, the target Virtuoso server redirects to a SPARQL endpoint that retrieves an RDF/XML representation of the requested entity.</para>
<programlisting>$ curl -I -H &quot;Accept: text/html&quot; http://demo.openlinksw.com/Northwind/Customer/ALFKI

HTTP/1.1 406 Not Acceptable
Server: Virtuoso/05.00.3016 (Solaris) x86_64-sun-solaris2.10-64 PHP5
Connection: close
Content-Type: text/html; charset=ISO-8859-1
Date: Mon, 16 Jul 2007 22:40:23 GMT
Accept-Ranges: bytes
Vary: negotiate,accept
Alternates: {&quot;ALFKI&quot; 0.9 {type application/rdf+xml}}
Content-Length: 0 
</programlisting><para> In this second cURL exchange, the target Virtuoso server indicates that there is no resource to deliver in the requested representation.
 It provides hints in the form of an alternate resource representation and URI that may be appropriate, i.e., an RDF/XML representation of the requested entity.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h2"> Deploying Linked Data using Virtuoso</bridgehead>
<para>The preceding sections described a generic approach to deploying linked data into the existing Web.
 We now turn our attention to Virtuoso, to describe its solution for linked data deployment.</para>
<para>In fact, Virtuoso&#39;s solution is to implement the generic approach outlined in the prior sections, using the twin pillars of Content Negotiation and URL rewriting.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h3"> The Virtuoso Rules-Based URL Rewriter</bridgehead>
<para>Virtuoso provides a URL rewriter that can be enabled for URLs matching specified patterns.
 Coupled with customizable HTTP response headers and response codes, Data-Web server administrators can configure highly flexible rules for driving content negotiation and URL rewriting.
 The key elements of the URL rewriter are:</para>
<itemizedlist mark="bullet" spacing="compact"><listitem>Rewriting rule </listitem>
<listitem>Each rule describes how to parse a single source URL, and how to compose the URL of the page ultimately returned in the &quot;Location:&quot; response headers </listitem>
<listitem>Every rewriting rule is uniquely identified internally (using IRIs).
</listitem>
<listitem>Two types of rule are supported, based on the syntax used to describe the source URL pattern matching: sprintf-based and regex-based.
</listitem>
<listitem>Rewrite rules list </listitem>
<listitem>A named ordered list of rewrite rules or rule lists where rules of the list are processed from top to bottom or in line with processing pipeline precedence instructions </listitem>
<listitem>Configuration API </listitem>
<listitem>The rewriter configuration API defines functions for creating, dropping, and enumerating rules and rule lists.
</listitem>
<listitem>Virtual hosts and virtual paths </listitem>
<listitem>URL rewriting is enabled by associating a rewrite rules list with a virtual directory</listitem>
</itemizedlist><para>Each of these elements is described in more detail below, although complete descriptions of the features or functions in question are not given.
 The intention here is to provide an overview of Virtuoso&#39;s URL rewriting capabilities and their application to deploying linked data.
 Please refer to the Virtuoso Reference Documentation for full details.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h3"> Conductor UI for the URL Rewriter</bridgehead>
<para>Virtuoso is a full-blown HTTP server in its own right.
 The HTTP server functionality co-exists with the product core (i.e., DBMS Engine, Web Services Platform, <ulink url="WebDAV">WebDAV</ulink> filesystem, and other components of the Universal Server).
 As a result, it has the ability to multi-home Web domains within a single instance across a variety of domain name and port combinations.
 In addition, it also enables the creation of multiple virtual directories per domain.</para>
<para>In addition to the basic functionality describe above, Virtuoso facilitates the association of URL Rewriting rules with the virtual directories associated with a hosted Web domain.</para>
<para>In all cases, Virtuoso enables you to configure virtual domains, virtual directories and URL rewrite rules for one or more virtual directories, via the (X)HTML-based Conductor Admin User Interface or a collection of Virtuoso Stored Procedure Language (PL)-based APIs.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h3"> Virtual Domains (Hosts) &amp; Directories</bridgehead>
<para>A Virtuoso virtual directory maps a logical path to a physical directory that is file system or <ulink url="WebDAV">WebDAV</ulink> based.
This mechanism allows physical locations to be hidden or simply reorganized.
 Virtual directory definitions are held in the system table DB.DBA.HTTP_PATH.
 Virtual directories can be administered in three basic ways:</para>
<itemizedlist mark="bullet" spacing="compact"><listitem>Using the Visual Administration Interface via a Web browser; </listitem>
<listitem>Using the functions vhost_define() and vhost_remove(); and </listitem>
<listitem>Using SQL statements to directly update the HTTP_PATH system table.</listitem>
</itemizedlist><bridgehead class="http://www.w3.org/1999/xhtml:h3"> &quot;Nice&quot; URLs vs.
 &quot;Long&quot; URLs</bridgehead>
<para>Although we are approaching the URL Rewriter from the perspective of deploying linked data, the Rewriter was developed with additional objectives in mind.
 These in turn have influenced the naming of some of the formal argument names in the Configuration API function prototypes.
 In the following sections, long URLs are those containing a query string with named parameters; nice (aka.
 source) URLs have data encoded in some other format.
 The primary goal of the Rewriter is to accept a nice URL from an application and convert this into a long URL, which then identifies the page that should actually be retrieved.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h3"> Rule Processing Mechanics</bridgehead>
<para>When an HTTP request is accepted by the Virtuoso HTTP server, the received nice URL is passed to an internal path translation function.
 This function takes the nice URL and, if the current virtual directory has a url_rewrite option set to an existing ruleset name, tries to match the corresponding rulesets and rules; that is, it performs a recursive traversal of any rule-list associated with it.
 For every rule in the rule-list, the same logic is applied (only the logic for regex-based rules is described; that for sprintf-based rules is very similar):</para>
<itemizedlist mark="bullet" spacing="compact"><listitem>The input for the rule is the resource URL as received from the HTTP header, i.e., the portion of the URL from the first solidus (&#39;/&#39;) after the host:port fields to the end of the URL.
</listitem>
<listitem>The input is normalized.
</listitem>
<listitem>The input is matched against the rule&#39;s regex.
 If the match fails, the rule is not applied and the next rule is tried.
 If the match succeeds, the result is a vector of values.
</listitem>
<listitem>If the URL contains a query string, the names and values of the parameters are decoded by split_and_decode().
</listitem>
<listitem>The names and values of any parameters in the request body are also decoded.
</listitem>
<listitem>The destination URL is composed: </listitem>
<listitem>The value of each parameter in the destination URL is taken from (in order of priority): <itemizedlist mark="bullet" spacing="compact"><listitem>the value of a parameter in the match result; </listitem>
<listitem>the value of a named parameter in the query string of the input nice URL; </listitem>
<listitem>if the original request was submitted by the POST method, the value of a named parameter in the body of the POST request; or </listitem>
<listitem>if a parameter value cannot be derived from one of these sources, the rule is not applied and the next rule is tried.</listitem>
</itemizedlist></listitem>
</itemizedlist><para>Note:</para>
<para>The path translation function described above is internal to the Web server, so its signature is not appropriate for Virtuoso/PL calls and thus is not published.
 Virtuoso/PL developers can harness the same functionality using the DB.DBA.URLREWRITE_APPLY API call.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h3"> Enabling URL Rewriting via the Virtuoso Conductor UI</bridgehead>
<para>The steps for configuring URL Rewrite rules via the Virtuoso Conductor are as follows:</para>
<orderedlist spacing="compact"><listitem>Assuming you are using the local demonstration database, load <ulink url="http://localhost:8890/conductor">http://localhost:8890/conductor</ulink> into your browser, and then proceed through the Conductor as follows: </listitem>
<listitem>Click the &quot;WebDAV &amp; HTTP&quot;, and &quot;HTTP Hosts &amp; Directories&quot; tabs </listitem>
<listitem>Pick the domain that contains the virtual directories to which the rules are to be applied (in this case the default was taken) </listitem>
<listitem>Click on the &quot;URL-rewrite&quot; link to create, delete, or edit a rule as shown below: </listitem>
<listitem>Create a Rule for HTML Representation Requests (via SPARQL SELECT Query) </listitem>
<listitem>Create a Rule for RDF Representation Requests (via SPARQL CONSTRUCT Query) </listitem>
<listitem>Then save and exit the Conductor, and test your rules with curl or any other User Agent.
<figure><graphic fileref="VirtLinkedDataDeployment/conductor_url_rewrite_ui_1.png" /></figure></listitem>
</orderedlist><bridgehead class="http://www.w3.org/1999/xhtml:h3"> Enabling URL Rewriting via Virtuoso PL</bridgehead>
<para>The vhost_define() API is used to define virtual hosts and virtual paths hosted by the Virtuoso HTTP server.
 URL rewriting is enabled through this function&#39;s opts parameter.
 opts is of type ANY, e.g., a vector of field-value pairs.
 Numerous fields are recognized for controlling different options.
 The field value url_rewrite controls URL rewriting.
 The corresponding field value is the IRI of a rule list to apply.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h4"> Configuration API</bridgehead>
<para>Virtuoso includes the following functions for managing URL rewriting rules and rule lists.
 The names are self-explanatory.</para>
<itemizedlist mark="bullet" spacing="compact"><listitem>DB.DBA.URLREWRITE_DROP_RULE — Deletes a rewriting rule </listitem>
<listitem>DB.DBA.URLREWRITE_CREATE_SPRINTF_RULE — Creates a rewriting rule which uses sprintf-based pattern matching </listitem>
<listitem>DB.DBA.URLREWRITE_CREATE_REGEX_RULE — Creates a rewriting rule which uses regular expression (regex) based pattern matching </listitem>
<listitem>DB.DBA.URLREWRITE_DROP_RULELIST — Deletes a rewriting rule list </listitem>
<listitem>DB.DBA.URLREWRITE_CREATE_RULELIST — Creates a rewriting rule list </listitem>
<listitem>DB.DBA.URLREWRITE_ENUMERATE_RULES — Lists all the rules whose IRI match the specified &#39;SQL like&#39; pattern </listitem>
<listitem>DB.DBA.URLREWRITE_ENUMERATE_RULELISTS — Lists all the rule lists whose IRIs match the specified &#39;SQL like&#39; pattern</listitem>
</itemizedlist><bridgehead class="http://www.w3.org/1999/xhtml:h4"> Creating Rewriting Rules</bridgehead>
<para>Rewriting rules take two forms: sprintf-based or regex-based.
 When used for nice URL to long URL conversion, the only difference between them is the syntax of format strings.
 The reverse long to nice conversion works only for sprintf-based rules, whereas regex-based rules are unidirectional.</para>
<para>For the purposes of describing how to make dereferenceable URIs for linked data, we will stick with the nice to long conversion using regex-based rules.</para>
<para>Regex rules are created using the URLREWRITE_CREATE_REGEX_RULE() function.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h5"> Function Prototype:</bridgehead>
<programlisting>URLREWRITE_CREATE_REGEX_RULE (
rule_iri,
allow_update,
nice_match,
nice_params,
nice_min_params,
target_compose,
target_params,
target_expn := null,
accept_pattern := null,
do_not_continue := 0,
http_redirect_code := null
);
</programlisting><para> </para>
<bridgehead class="http://www.w3.org/1999/xhtml:h5"> Parameters:</bridgehead>
<itemizedlist mark="bullet" spacing="compact"><listitem>rule_iri: VARCHAR.
 The rule&#39;s name / identifier </listitem>
<listitem>allow_update: INTEGER.
 Indicates whether the rule can be updated.
 Non-zero indicates yes; 0 indicates no.
 The update is subject to the following rules: <itemizedlist mark="bullet" spacing="compact"><listitem>If the given rule_iri is already in use as a rule list identifier, an error is signaled.
</listitem>
<listitem>If the given rule_iri is already in use as a rule identifier and allow_update for the existing rule is 0, an error is signaled.
</listitem>
<listitem>If the given rule_iri is already in use as a rule identifier and allow_update for the existing rule is non-zero, the existing rule is updated.
</listitem>
</itemizedlist></listitem>
<listitem>nice_match: VARCHAR.
 A regex match expression to parse the URL into a vector of occurrences.
</listitem>
<listitem>nice_params: ANY.
 A vector of the names of the parsed parameters.
 The length of the vector should be equal to the number of &#39;(...)&#39; specifiers in the format string.
</listitem>
<listitem>nice_min_params: INTEGER.
 Used to specify the minimum number of sprintf format patterns to be matched in order to trigger the given rule.
 It only affects sprintf rules and has no effect for regex rules.
</listitem>
<listitem>target_compose: VARCHAR.
 A regex compose expression for the URL of the destination page.
</listitem>
<listitem>target_params: ANY.
 A vector of names of parameters that should be passed to the compose expression (target_compose) as $1, $2 and so on.
</listitem>
<listitem>target_expn: VARCHAR.
 Optional SQL text that should be executed instead of a regex compose call.
</listitem>
<listitem>accept_pattern: VARCHAR.
 A regex expression to match the HTTP Accept header </listitem>
<listitem>do_not_continue: INTEGER.
 If the given rule satisfies the match conditions, 1 signifies do not try the next rule from same rule list, and 0 signifies try the next rule.
</listitem>
<listitem>http_redirect_code: INTEGER.
 NULL or the integer values 301, 302, 303, or 406, are currently allowed.
 If a 3xx redirect code is given, an HTTP redirect response will be sent back to client.
 If NULL is specified, the server will process the redirect internally.</listitem>
</itemizedlist><bridgehead class="http://www.w3.org/1999/xhtml:h3"> Example - URL Rewriting For the Northwind Linked Data View</bridgehead>
<para>In our Linked Data Views of SQL white paper we covered the process of declaring Linked Data Views of SQL data via the Virtuoso Meta-schema Language.
 When producing the Linked Data Views we used the Virtuoso &quot;Demo&quot; database, which is very similar to the &quot;Northwind&quot; database that comes as an installation bundle with Microsoft ACCESS and SQL Server.</para>
<para>The Northwind schema is comprised of commonly understood SQL Tables including Customers, Orders, Employees, Products, Product Categories, Shippers, Countries, Provinces, etc.</para>
<para>An Linked Data View of SQL data is an RDF Named Graph (RDF data set) comprised of RDF Linked Data (triples) stored in a Virtuoso Quad Store (the native RDF Data Management realm of Virtuoso).</para>
<para>In the example that follows, we are going interact with Linked Data deployed into the Data-Web from a live instance of Virtuoso, which uses the URL Rewrite rules from the prior section.</para>
<para>The components used in the example are as follows:</para>
<orderedlist spacing="compact"><listitem>Virtuoso SPARQL Endpoint: <ulink url="http://demo.openlinksw.com/sparql">http://demo.openlinksw.com/sparql</ulink> </listitem>
<listitem>Named RDF Graph: <ulink url="http://demo.openlinksw.com/Northwind">http://demo.openlinksw.com/Northwind</ulink> </listitem>
<listitem>Entity ID - <ulink url="http://demo.openlinksw.com/Northwind/Customer/ALFKI#this">http://demo.openlinksw.com/Northwind/Customer/ALFKI#this</ulink> </listitem>
<listitem>Information Resource: <ulink url="http://demo.openlinksw.com/Northwind/Customer/ALFKI">http://demo.openlinksw.com/Northwind/Customer/ALFKI</ulink> </listitem>
<listitem>Interactive SPARQL Query Builder (iSPARQL) - <ulink url="http://demo.openlinksw.com/DAV/JS/isparql/index.html">http://demo.openlinksw.com/DAV/JS/isparql/index.html</ulink></listitem>
</orderedlist><bridgehead class="http://www.w3.org/1999/xhtml:h4"> Interacting with Linked Data via RDF Browser</bridgehead>
<para>Steps:</para>
<orderedlist spacing="compact"><listitem>Start the browser - <ulink url="http://demo.openlinksw.com/DAV/JS/rdfbrowser/index.html">http://demo.openlinksw.com/DAV/JS/rdfbrowser/index.html</ulink> </listitem>
<listitem>Enter the Information Resource URI, <ulink url="http://demo.openlinksw.com/Northwind/Customer/ALFKI">http://demo.openlinksw.com/Northwind/Customer/ALFKI</ulink>, into the input field labeled &quot;URI&quot; <figure><graphic fileref="VirtLinkedDataDeployment/rdf_browser2.png" /></figure> </listitem>
<listitem>Click on the &quot;Query&quot; button or simply hit &quot;Enter&quot; after typing (or pasting in) the Information Resource URI </listitem>
<listitem>For the purpose of this exercise, view the data returned via the &quot;Navigator&quot; Viewer <figure><graphic fileref="VirtLinkedDataDeployment/rdf_browser3.png" /></figure> </listitem>
<listitem>Click on the &quot;Raw Triples&quot; viewer tab and observe the exposure of the Entity <ulink url="http://demo.openlinksw.com/Northwind/Customer/ALFKI#this">http://demo.openlinksw.com/Northwind/Customer/ALFKI#this</ulink> via the Triple based (Subject, Predicate, Object) records in the results table.
<figure><graphic fileref="VirtLinkedDataDeployment/rdf_browser4.png" /></figure></listitem>
</orderedlist><bridgehead class="http://www.w3.org/1999/xhtml:h4"> Interacting with Linked Data via iSPARQL</bridgehead>
<para>We can interact with the same Information Resource and associated RDF using the iSPARQL Query tool as follows:</para>
<orderedlist spacing="compact"><listitem>Start the Query Builder by entering the following into your browser: <ulink url="http://demo.openlinksw.com/isparql">http://demo.openlinksw.com/isparql</ulink> You will be presented with a default Query By Example (QBE) canvas that includes a default Graph Pattern and a default URI.
 Change the URI to: <ulink url="http://demo.openlinksw.com/Northwind/Customer/ALFKI">http://demo.openlinksw.com/Northwind/Customer/ALFKI</ulink> (Information Resource as a Data Resource in the context of RDF) <figure><graphic fileref="VirtLinkedDataDeployment/isparql_qbe_1.png" /></figure> </listitem>
<listitem>Then execute the default query (which simply gets a list of concepts), by clicking on the &quot;&gt;&quot; button.
Note: There is a single record in the result table.
 It indicates that there is a single concept, Organization, as defined by the FOAF schema.
<figure><graphic fileref="VirtLinkedDataDeployment/isparql_qbe_2.png" /></figure> </listitem>
<listitem>Click on the foaf:Organization record, and you will be presented with a Data Web-optimized hyperlink that presents you with three options: Dereference, Explore, and (X)HTML Page Open.
<figure><graphic fileref="VirtLinkedDataDeployment/isparql_qbe_3.png" /></figure> </listitem>
<listitem>Click Explore (since you are interested in &quot;instance data&quot; for the foaf:Organization concept, as opposed to the schema definitions of said concept).
 You will be presented with <ulink url="http://demo.openlinksw.com/Northwind/Customer/ALFKI#this">http://demo.openlinksw.com/Northwind/Customer/ALFKI#this</ulink> which is an RDF Entity ID of a foaf:Organization instance.
<figure><graphic fileref="VirtLinkedDataDeployment/isparql_qbe_4.png" /></figure> </listitem>
<listitem>Click on the <ulink url="http://demo.openlinksw.com/Northwind/Customer/ALFKI">http://demo.openlinksw.com/Northwind/Customer/ALFKI</ulink> record, and you will once again be presented with the enhanced hyperlink and its options.
 This time, click Dereference, since you are interested in the description of the entity <ulink url="http://demo.openlinksw.com/Northwind/Customer/ALFKI">http://demo.openlinksw.com/Northwind/Customer/ALFKI</ulink>, as opposed to all the records in the RDF database that are related to it.
<figure><graphic fileref="VirtLinkedDataDeployment/isparql_qbe_5.png" /></figure> <figure><graphic fileref="VirtLinkedDataDeployment/isparql_qbe_6.png" /></figure></listitem>
</orderedlist><para> </para>
<bridgehead class="http://www.w3.org/1999/xhtml:h4"> Interacting with Linked Data via a standard Document Web Browser</bridgehead>
<para>In the prior sections, we used the <ulink url="OpenLink">OpenLink</ulink> RDF Browser and iSPARQL Query-By-Example tools to interact with RDF Entities via associated Information Resources.
 Each of these tools includes a Resource Save feature that enables you to save an RDF Browser session or an iSPARQL Query for future reuse.
 In either scenario the end-product is a Dynamic Linked Data Page — a Web Information Resource (document) that includes links to RDF based Linked Data.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h5"> Saved Browser Session</bridgehead>
<para>Steps:</para>
<orderedlist spacing="compact"><listitem>From your RDF Browser session, go to the Session &gt;&gt; Save menu item.
<figure><graphic fileref="VirtLinkedDataDeployment/rdf_browser5.png" /></figure> </listitem>
<listitem>Select a directory location (note: this is a <ulink url="WebDAV">WebDAV</ulink> location in the Virtuoso Server) and then enter a file name, e.g., ALFKI_Linked_Datay.
 The saved file will automatically be assigned the extension .wqx.
<figure><graphic fileref="VirtLinkedDataDeployment/rdf_browser6.png" /></figure> </listitem>
<listitem>Open a standard browser instance on your internet device (desktop, notebook, phone, etc.), and enter the URL for the location into which you just saved your browser session, e.g., <ulink url="http://demo.openlinksw.com/DAV/home/demo/Public/Queries/SQLRDFIntegraton/">http://demo.openlinksw.com/DAV/home/demo/Public/Queries/SQLRDFIntegraton/</ulink> (based on our example).
<figure><graphic fileref="VirtLinkedDataDeployment/saving_to_webdav_1.png" /></figure> </listitem>
<listitem>Click on the file ALFKI_Linked_Data.wqx, which will then reveal a browser session-oriented Linked Data page.
<figure><graphic fileref="VirtLinkedDataDeployment/saving_to_webdav_3.png" /></figure> <figure><graphic fileref="VirtLinkedDataDeployment/rdf_browser8.png" /></figure></listitem>
</orderedlist><bridgehead class="http://www.w3.org/1999/xhtml:h5"> Saved iSPARQL Query</bridgehead>
<para>Steps:</para>
<orderedlist spacing="compact"><listitem>From your iSPARQL Session, pick the File &gt;&gt; Save (if first time) or File &gt;&gt; Save As (for saving to different name) <figure><graphic fileref="VirtLinkedDataDeployment/isparql_qbe_7.png" /></figure> </listitem>
<listitem>Type in a name for your saved query, e.g., ALFKI_Linked_Data.
 Note that you have a number of file type options.
 For this exercise, we are going to choose the .isparql type, since we are attempting to create a Dynamic Linked Data page.
<figure><graphic fileref="VirtLinkedDataDeployment/isparql_qbe_save_1.png" /></figure> </listitem>
<listitem>Open a standard browser instance on your internet device (desktop, notebook, phone, etc.), and enter the URL for the location into which you save your browser session, e.g., <ulink url="http://demo.openlinksw.com/DAV/home/demo/Public/Queries/SQLRDFIntegraton/">http://demo.openlinksw.com/DAV/home/demo/Public/Queries/SQLRDFIntegraton/</ulink> (based on our example).
<figure><graphic fileref="VirtLinkedDataDeployment/saving_to_webdav_2.png" /></figure> </listitem>
<listitem>Click on the file ALFKI_Linked_Data.isparql, and then interact with the Linked Data page.
<figure><graphic fileref="VirtLinkedDataDeployment/isparql_linked_data_page1.png" /></figure></listitem>
</orderedlist><bridgehead class="http://www.w3.org/1999/xhtml:h4"> Northwind URL Rewriting Verification Using curl</bridgehead>
<para>As illustrated earlier, the curl utility provides a useful tool for verifying HTTP server responses and rewriting rules.
The curl exchanges below show the URL rewriting rules defined for the Northwind Linked Data View being applied.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h5">Example 1</bridgehead>
<programlisting>$ curl -I -H &quot;Accept: text/html&quot; http://demo.openlinksw.com/Northwind/Customer/ALFKI 

HTTP/1.1 303 See Other 
Server: Virtuoso/05.00.3016 (Solaris) x86_64-sun-solaris2.10-64 PHP5 
Connection: close 
Content-Type: text/html; charset=ISO-8859-1
Date: Tue, 14 Aug 2007 13:30:02 GMT 
Accept-Ranges: bytes 
Location:  /isparql/execute.html?query=SELECT%20%3Fp%20%3Fo%20FROM%20%3Chttp%3A//dem
o.openlinksw.com/Northwind%3E%20WHERE%20{%20%3Chttp%3A//demo.openlinksw.com/Northwin
d/Customer/ALFKI%23this%3E%20%3Fp%20%3Fo%20}&amp;endpoint=/sparql
Content-Length: 0 
</programlisting><para> </para>
<bridgehead class="http://www.w3.org/1999/xhtml:h5">Example 2</bridgehead>
<programlisting>$ curl -I -H &quot;Accept: application/rdf+xml&quot; http://demo.openlinksw.com/Northwind/Cust
omer/ALFKI

HTTP/1.1 303 See Other
Server: Virtuoso/05.00.3016 (Solaris) x86_64-sun-solaris2.10-64 PHP5 
Connection: close
Content-Type: text/html; charset=ISO-8859-1
Date: Tue, 14 Aug 2007 13:30:22 GMT
Accept-Ranges: bytes 
Location: /sparql?query=CONSTRUCT+{+%3Chttp%3A//demo.openlinksw.com/Northwind/Custom
er/ALFKI%23this%3E+%3Fp+%3Fo+}+FROM+%3Chttp%3A//demo.openlinksw.com/Northwind%3E+WHE
RE+{+%3Chttp%3A//demo.openlinksw.com/Northwind/Customer/ALFKI%23this%3E+%3Fp+%3Fo+}&amp;
format=application/rdf%2Bxml
Content-Length: 0 
</programlisting><para> </para>
<bridgehead class="http://www.w3.org/1999/xhtml:h5">Example 3</bridgehead>
<programlisting>$ curl -I -H &quot;Accept: text/html&quot; http://demo.openlinksw.com/Northwind/Customer/ALFKI
#this 

HTTP/1.1 404 Not Found 
Server: Virtuoso/05.00.3016 (Solaris) x86_64-sun-solaris2.10-64 PHP5 
Connection: Keep-Alive
Content-Type: text/html; charset=ISO-8859-1 
Date: Tue, 14 Aug 2007 13:31:01 GMT 
Accept-Ranges: bytes 
Content-Length: 0 
</programlisting><para> The output above shows how RDF entities from the Data-Web, in this case customer ALFKI, are exposed in the Document Web.
The power of SPARQL coupled with URL rewriting enables us to produce results in line with the desired representation.
A SPARQL SELECT or CONSTRUCT query is used depending on whether the requested representation is text/html or application/rdf+xml, respectively.</para>
<para>The 404 response in Example 3 indicates that no HTML representation is available for entity ALFKI#this.
 In most cases, a URI of this form (containing a &#39;#&#39; fragment identifier) will not reach the server.
 This example supposes that it does, i.e., the RDF client and network routing allows the suffixed request.
 The presence of the #this suffix implicitly states <ulink url="">
 that this is a request for a data resource in the Data-Web realm, not a document resource from the Document Web.
 <ulink url="#FootNote2">Note 2</ulink></ulink></para>
<para>Rather than return 404, we could instead choose to construct our rewriting rules to perform a 303 redirect, so that the response for ALFKI#this in Example 3 becomes the same as that for ALFKI in Example 1.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h3"> Transparent Content Negotiation</bridgehead>
<para>So as not to overload our preceding description of Linked Data deployment with excessive detail, the description of content negotiation presented thus far was kept deliberately brief.
 This section discusses content negotiation in more detail.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h4"> HTTP/1.1 Content Negotiation</bridgehead>
<para>Recall that a resource (conceptual entity) identified by a URI may be associated with more than one representation (e.g., multiple languages, data formats, sizes, resolutions).
 If multiple representations are available, the resource is referred to as negotiable and each of its representations is termed a variant.
 For instance, a Web document resource, named &#39;ALFKI&#39; may have three variants: alfki.xml, alfki.html, and alfki.txt, all representing the same data.
 Content negotiation provides a mechanism for selecting the best variant.</para>
<para>As outlined in the earlier brief discussion of content negotiation, when a user agent requests a resource, it can include with the request Accept headers (Accept, Accept-Language, Accept-Charset, Accept-Encoding, etc.) which express the user preferences and user agent capabilities.
 The server then chooses and returns the best variant based on the Accept headers.
Because the selection of the best resource representation is made by the server, this scheme is classed as server-driven negotiation.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h4"> Transparent Content Negotiation</bridgehead>
<para>An alternative content negotiation mechanism is Transparent Content Negotiation (TCN), a protocol defined by RFC2295.
 TCN offers a number of benefits over standard HTTP/1.1 negotiation, for suitably enabled user agents.</para>
<para>RFC2295 introduces a number of new HTTP headers including the Negotiate request header, and the TCN and Alternates response headers.
 (Krishnamurthy et al note that although the HTTP/1.1 specification reserved the Alternates header for use in agent- driven negotiation, it was not fully specified.
 Consequently under a pure HTTP/1.1 implementation as defined by RFC2616, server-driven content negotiation is the only option.
 RFC2295 addresses this issue.)</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h5"> Deficiencies of HTTP/1.1 Server-Driven Negotiation</bridgehead>
<para>Weaknesses of server-driven negotiation highlighted by RFCs 2295 and 2616 include:</para>
<itemizedlist mark="bullet" spacing="compact"><listitem>Inefficiency — Sending details of a user agent&#39;s capabilities and preferences with every request is very inefficient, not least because very few Web resources have multiple variants, and expensive in terms of the number of Accept headers required to fully describe all but the most simple browser&#39;s capabilities.
</listitem>
<listitem>Server doesn&#39;t always know &#39;best&#39; — Having the server decide on the &#39;best&#39; variant may not always result in the most suitable resource representation being returned to the client.
 The user agent might often be better placed to decide what is best for its needs.</listitem>
</itemizedlist><bridgehead class="http://www.w3.org/1999/xhtml:h5"> Variant Selection By User Agent</bridgehead>
<para>Rather than rely on server-driven negotiation and variant selection by the server, a user agent can take full control over deciding the best variant by explicitly requesting transparent content negotiation through the Negotiate request header.
The negotiation is &#39;transparent&#39; because it makes all the variants on the server visible to the agent.</para>
<para>Under this scheme, the server sends the user agent a list, represented in an Alternates header, containing the available variants and their properties.
 The user agent can then choose the best variant itself.
 Consequently, the agent no longer needs to send large Accept headers describing in detail its capabilities and preferences.
 (However, unless caching is used, user-agent driven negotiation does suffer from the disadvantage of needing a second request to obtain the best representation.
By sending its best guess as the first response, server driven negotiation avoids this second request if the initial best guess is acceptable.)</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h5"> Variant Selection By Server</bridgehead>
<para>As well as variant selection by the user agent, TCN allows the server to choose on behalf of the user agent if the user agent explicitly allows it through the Negotiate request header.
 This option allows the user agent to send smaller Accept headers containing enough information to allow the server to choose the best variant and return it directly.
 The server&#39;s choice is controlled by a &#39;remote variant selection algorithm&#39; as defined in RFC2296.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h5"> Variant Selection By End-User</bridgehead>
<para>A further option is to allow the end-user to select a variant, in case the choice made by negotiation process is not optimal.
For instance, the user agent could display an HTML-based &#39;pick list&#39; of variants constructed from the variant list returned by the server.
 Alternatively the server could generate this pick list itself and include it in the response to a user agent&#39;s request for a variant list.
 (Virtuoso currently responds this way.)</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h3"> Transparent Content Negotiation in Virtuoso HTTP Server</bridgehead>
<para>The following section describes the Virtuoso HTTP server&#39;s TCN implementation which is based on RFC2295, but without &quot;Feature&quot; negotiation.
 <ulink url="OpenLink">OpenLink</ulink>&#39;s RDF rich clients, iSparql and the <ulink url="OpenLink">OpenLink</ulink> RDF Browser, both support TCN.
 User agents which do not support transparent content negotiation continue to be handled using HTTP/1.1 style content negotiation (whereby server-side selection is the only option - the server selects the best variant and returns a list of variants in an Alternates response header).</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h4"> Describing Resource Variants</bridgehead>
<para>In order to negotiate a resource, the server needs to be given information about each of the variants.
 Variant descriptions are held in SQL table HTTP_VARIANT_MAP.
 The descriptions themselves can be created, updated or deleted using Virtuoso/PL or through the Conductor UI.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h5"> HTTP_VARIANT_MAP Table Definition</bridgehead>
<para>The table definition is as follows:</para>
<programlisting>create table DB.DBA.HTTP_VARIANT_MAP (
  VM_ID integer identity, -- unique ID 
  VM_RULELIST varchar, -- HTTP rule list name 
  VM_URI varchar, -- name of requested resource e.g. &#39;page&#39; 
  VM_VARIANT_URI varchar, -- name of variant e.g. &#39;page.xml&#39;, &#39;page.de.html&#39; etc. 
  VM_QS float, -- Source quality, a number in the range 0.001-1.000, with 3 digit precision 
  VM_TYPE varchar, -- Content type of the variant e.g. text/xml 
  VM_LANG varchar, -- Content language e.g. &#39;en&#39;, &#39;de&#39; etc. 
  VM_ENC varchar, -- Content encoding e.g. &#39;utf-8&#39;, &#39;ISO-8892&#39; etc. 
  VM_DESCRIPTION long varchar, -- a human readable description about the variant e.g. &#39;Profile in RDF format&#39; 
  VM_ALGO int default 0, -- reserved for future use 
  primary key (VM_RULELIST, VM_URI, VM_VARIANT_URI)
 ) 
create unique index HTTP_VARIANT_MAP_ID on DB.DBA.HTTP_VARIANT_MAP (VM_ID)
</programlisting><bridgehead class="http://www.w3.org/1999/xhtml:h5"> Configuration using Virtuoso/PL</bridgehead>
<para>Two functions are provided for adding or updating, or removing variant descriptions using Virtuoso/PL:</para>
<span style="color: red">
      UNKNOWN tag:
      http://www.w3.org/1999/xhtml:h6 Adding or Updating a Resource Variant:</span>
<programlisting>DB.DBA.HTTP_VARIANT_ADD ( 
  in rulelist_uri varchar, -- HTTP rule list name 
  in uri varchar, -- Requested resource name e.g. &#39;page&#39; 
  in variant_uri varchar, -- Variant name e.g. &#39;page.xml&#39;, &#39;page.de.html&#39; etc. 
  in mime varchar, -- Content type of the variant e.g. text/xml 
  in qs float := 1.0, -- Source quality, a floating point number with 3 digit precision in 0.001-1.000 range 
  in description varchar := null, -- a human readable description of the variant e.g. &#39;Profile in RDF format&#39; 
  in lang varchar := null, -- Content language e.g. &#39;en&#39;, &#39;bg&#39;. &#39;de&#39; etc. 
  in enc varchar := null -- Content encoding e.g. &#39;utf-8&#39;, &#39;ISO-8892&#39; etc. 
)
</programlisting><para> </para>
<span style="color: red">
      UNKNOWN tag:
      http://www.w3.org/1999/xhtml:h6Removing a Resource Variant</span>
<programlisting>DB.DBA.HTTP_VARIANT_REMOVE ( 
  in rulelist_uri varchar, -- HTTP rule list name 
  in uri varchar, -- Name of requested resource e.g. &#39;page&#39; 
  in variant_uri varchar := &#39;%&#39; -- Variant name filter 
)
</programlisting><para> </para>
<bridgehead class="http://www.w3.org/1999/xhtml:h5"> Configuration using Conductor UI</bridgehead>
<para>The Conductor &#39;Content negotiation&#39; panel for describing resource variants and configuring content negotiation is depicted below.
 It can be reached by selecting the &#39;HTTP Hosts &amp; Directories&#39; tab under the &#39;WebDAV &amp; HTTP&#39; menu item, then selecting the &#39;URL rewrite&#39; option for a logical path listed amongst those for the relevant HTTP host, e.g., &#39;{Default Web Site}&#39;.</para>
<para>The screen snapshot shows the variant descriptions created by issuing the HTTP_VARIANT_ADD and VHOST_DEFINE Virtuoso/PL calls detailed in the examples at the end of this section.
 Obviously these definitions could instead have been created entirely &#39;from scratch&#39; through the Conductor UI.</para>
<para>The input fields reflect the supported &#39;dimensions&#39; of negotiation which include content type, language and encoding.
Quality values corresponding to the options for &#39;Source Quality&#39; are as follows:</para>

<table><title /><tgroup><thead /><tbody>
<row />
<row><entry>perfect representation</entry><entry>1.000</entry></row>
<row><entry>threshold of noticeable loss of quality</entry><entry>0.900</entry></row>
<row><entry>noticeable, but acceptable quality reduction</entry><entry>0.800</entry></row>
<row><entry>barely acceptable quality</entry><entry>0.500</entry></row>
<row><entry>severely degraded quality</entry><entry>0.300</entry></row>
<row><entry>completely degraded quality</entry><entry>0.000</entry></row>
</tbody></tgroup></table>
<bridgehead class="http://www.w3.org/1999/xhtml:h4"> Variant Selection Algorithm</bridgehead>
<para>When a user agent instructs the server to select the best variant, Virtuoso does so using the selection algorithm below:</para>
<para>If a virtual directory has URL rewriting enabled (has the &#39;url_rewrite&#39; option set), the web server:</para>
<itemizedlist mark="bullet" spacing="compact"><listitem>Looks in DB.DBA.HTTP_VARIANT_MAP for a VM_RULELIST matching the one specified in the &#39;url_rewrite&#39; option</listitem>
</itemizedlist><itemizedlist mark="bullet" spacing="compact"><listitem>If present, it loops over all variants for which VM_URI is equal to the resource requested</listitem>
</itemizedlist><itemizedlist mark="bullet" spacing="compact"><listitem>For every variant it calculates the source quality based on the value of VM_QS and the source quality given by the user agent</listitem>
</itemizedlist><itemizedlist mark="bullet" spacing="compact"><listitem>If the best variant is found, it adds TCN HTTP headers to the response and passes the VM_VARIANT_URI to the URL rewriter</listitem>
</itemizedlist><itemizedlist mark="bullet" spacing="compact"><listitem>If the user agent has asked for a variant list, it composes such a list and returns an &#39;Alternates&#39; HTTP header with response code 300</listitem>
</itemizedlist><itemizedlist mark="bullet" spacing="compact"><listitem>If no URL rewriter rules exist for the target URL, the web server returns the content of the dereferenced VM_VARIANT_URI.</listitem>
</itemizedlist><para>The server may return the best-choice resource representation or a list of available resource variants.
 When a user agent requests transparent negotiation, the web server returns the TCN header &quot;choice&quot;.
 When a user agent asks for a variant list, the server returns the TCN header &quot;list&quot;.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h4"> Examples</bridgehead>
<para>In this example we assume the following files have been uploaded to the Virtuoso <ulink url="WebDAV">WebDAV</ulink> server, with each containing the same information but in different formats:</para>
<itemizedlist mark="bullet" spacing="compact"><listitem>/DAV/TCN/page.xml - a XML variant </listitem>
<listitem>/DAV/TCN/page.html - a HTML variant </listitem>
<listitem>/DAV/TCN/page.txt - a text variant</listitem>
</itemizedlist><para>We add TCN rules and define a virtual directory:</para>
<programlisting>DB.DBA.HTTP_VARIANT_ADD (&#39;http_rule_list_1&#39;, &#39;page&#39;, &#39;page.html&#39;, &#39;text/html&#39;, 
0.900000, &#39;HTML variant&#39;); DB.DBA.HTTP_VARIANT_ADD (&#39;http_rule_list_1&#39;, &#39;page&#39;, 
&#39;page.txt&#39;, &#39;text/plain&#39;, 0.500000, &#39;Text document&#39;); DB.DBA.HTTP_VARIANT_ADD 
(&#39;http_rule_list_1&#39;, &#39;page&#39;, &#39;page.xml&#39;, &#39;text/xml&#39;, 1.000000, &#39;XML variant&#39;); 
DB.DBA.VHOST_DEFINE (lpath=&gt;&#39;/DAV/TCN/&#39;, ppath=&gt;&#39;/DAV/TCN/&#39;, is_dav=&gt;1, 
vsp_user=&gt;&#39;dba&#39;, opts=&gt;vector (&#39;url_rewrite&#39;, &#39;http_rule_list_1&#39;));
</programlisting><para> Having done this we can now test the setup with a suitable HTTP client, in this case the curl command line utility.
 In the following examples, the curl client supplies Negotiate request headers containing content negotiation directives which include:</para>
<itemizedlist mark="bullet" spacing="compact"><listitem>&quot;trans&quot; — The user agent supports transparent content negotiation for the current request.
</listitem>
<listitem>&quot;vlist&quot; — The user agent requests that any transparently negotiated response for the current request includes an Alternates header with the variant list bound to the negotiable resource.
 Implies &quot;trans&quot;.
</listitem>
<listitem>&quot;*&quot; — The user agent allows servers and proxies to run any remote variant selection algorithm.</listitem>
</itemizedlist><para>The server returns a TCN response header signaling that the resource is transparently negotiated and either a choice or a list response as appropriate.</para>
<para>In the first curl exchange, the user agent indicates to the server that, of the formats it recognizes, HTML is preferred and it instructs the server to perform transparent content negotiation.
 In the response, the Vary header field expresses the parameters the server used to select a representation, i.e., only the Negotiate and Accept header fields are considered.</para>
<programlisting>$ curl -i -H &quot;Accept: text/xml;q=0.3,text/html;q=1.0,text/plain;q=0.5,*/*;q=0.3&quot; -H 
&quot;Negotiate: *&quot; http://localhost:8890/DAV/TCN/page 

HTTP/1.1 200 OK 
Server: Virtuoso/05.00.3021 (Linux) i686-pc-linux-gnu VDB 
Connection: Keep-Alive 
Date: Wed, 31 Oct 2007 15:43:18 GMT 
Accept-Ranges: bytes 
TCN: choice 
Vary: negotiate,accept 
Content-Location: page.html 
Content-Type: text/html 
ETag: &quot;14056a25c066a6e0a6e65889754a0602&quot; 
Content-Length: 49

&lt;html&gt; &lt;body&gt; some html &lt;/body&gt; &lt;/html&gt;
</programlisting><para>Next, the source quality values are adjusted so that the user agent indicates that XML is its preferred format.</para>
<programlisting>$ curl -i -H &quot;Accept: text/xml,text/html;q=0.7,text/plain;q=0.5,*/*;q=0.3&quot; -H &quot;Negot
iate: *&quot; http://localhost:8890/DAV/TCN/page 

HTTP/1.1 200 OK 
Server: Virtuoso/05.00.3021 (Linux) i686-pc-linux-gnu VDB 
Connection: Keep-Alive 
Date: Wed, 31 Oct 2007 15:44:07 GMT 
Accept-Ranges: bytes 
TCN: choice 
Vary: negotiate,accept 
Content-Location: page.xml 
Content-Type: text/xml 
ETag: &quot;8b09f4b8e358fcb7fd1f0f8fa918973a&quot; 
Content-Length: 39

&lt;?xml version=&quot;1.0&quot; ?&gt; &lt;a&gt;some xml&lt;/a&gt;
</programlisting><para>In the final example, the user agent wants to decide itself which is the most suitable representation, so it asks for a list of variants.
 The server provides the list, in the form of an Alternates response header, and, in addition, sends an HTML representation of the list so that the end user can decide on the preferred variant himself if the user agent is unable to.</para>
<programlisting>$ curl -i -H &quot;Accept: text/xml,text/html;q=0.7,text/plain;q=0.5,*/*;q=0.3&quot; -H &quot;Negot
iate: vlist&quot; http://localhost:8890/DAV/TCN/page 

HTTP/1.1 300 Multiple Choices 
Server: Virtuoso/05.00.3021 (Linux) i686-pc-linux-gnu VDB 
Connection: close 
Content-Type: text/html; charset=ISO-8859-1 
Date: Wed, 31 Oct 2007 15:44:35 GMT 
Accept-Ranges: bytes 
TCN: list 
Vary: negotiate,accept 
Alternates: {&quot;page.html&quot; 0.900000 {type text/html}}, {&quot;page.txt&quot; 0.500000 {type text
/plain}}, {&quot;page.xml&quot; 1.000000 {type text/xml}} 
Content-Length: 368

&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML 2.0//EN&quot;&gt;
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;300 Multiple Choices&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h1&gt;Multiple Choices&lt;/h1&gt;
Available variants: 
&lt;ul&gt;
&lt;li&gt;
&lt;a href=&quot;page.html&quot;&gt;HTML variant&lt;/a&gt;, type text/html&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;page.txt&quot;&gt;Text document&lt;/a&gt;, type text/plain&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;page.xml&quot;&gt;XML variant&lt;/a&gt;, type text/xml&lt;/li&gt;
&lt;/ul&gt;
&lt;/body&gt;
&lt;/html&gt;
</programlisting><para> </para>
<bridgehead class="http://www.w3.org/1999/xhtml:h3"> Glossary</bridgehead>
<itemizedlist mark="bullet" spacing="compact"><listitem><emphasis>class</emphasis>: A concept in a domain of interest.
 A class describes the common attributes and behaviors shared by entities belonging to the same group by virtue of their common characteristics.
</listitem>
<listitem><emphasis>content negotiation</emphasis>: A mechanism defined in HTTP which supports serving different representations of a URL-addressable resource.
 An HTTP client can indicate which representation formats it understands and prefers.
</listitem>
<listitem><emphasis>cURL</emphasis>: A command line tool for transferring files to or from a URL.
 It writes to standard output by default and provides a good tool for simulating a web browser&#39;s interaction with an HTTP server.
</listitem>
<listitem><emphasis>data resource</emphasis>: same as data source </listitem>
<listitem><emphasis>data source</emphasis>: A source of data (e.g., a place that provides access to property values associated with one or more Entities).
</listitem>
<listitem><emphasis>data space</emphasis>: A moniker for Web-accessible atomic containers that manage and expose data, information, services, processes, and knowledge.
 Data Spaces are fundamentally problem-domain-specific database applications with the benefit of being data model and query language agnostic.
</listitem>
<listitem><emphasis>dereferencing</emphasis>: The act of accessing and retrieving data, in desired representation, from a location identified by URL.
</listitem>
<listitem><emphasis>document resource</emphasis>: A Web information resource in a specific representation that is identifiable and accessible via a URL.
 Documents are the dominant information resource form on the Document Web (i.e., the current Web).
</listitem>
<listitem><emphasis>Document Web</emphasis>: Web of Linked Documents.
</listitem>
<listitem><emphasis>entity</emphasis>: Something, real or conceptual, which exists apart from other things.
</listitem>
<listitem><emphasis>entity ID</emphasis>: A unique identifier for an entity, uniquely identifying and distinguishing a particular entity instance from other similar entities (typically of the same type or class).
</listitem>
<listitem><emphasis>entity set</emphasis>: A collection of entities all belonging to the same class.
</listitem>
<listitem><emphasis>HTTP</emphasis>: Hypertext Transport Protocol.
</listitem>
<listitem><emphasis>HTTP header</emphasis>: A text record exchanged between an HTTP client and server, which forms part of an HTTP request or HTTP response message.
 A request consists of a method (or verb), headers, and an optional message body.
 The request header fields allow the client to send additional information about the request and the client itself.
A response consists of a status line, headers, and an optional message body.
 A response header typically contains information about the data being returned and about the server itself.
</listitem>
<listitem><emphasis>Hypertext Transport Protocol)</emphasis>: A communication protocol for information transfer on the World Wide Web.
</listitem>
<listitem><emphasis>information resource</emphasis>: An encapsulation of data and representation that forms the basic payload unit (packet) on the Web Information Bus.
</listitem>
<listitem><emphasis>IRI (Internationalized Resource Identifier)</emphasis>: An internationalized version of a Uniform Resource Identifier (URI).
 While URIs are limited to a subset of the ASCII character set, IRIs may contain any Unicode character.
</listitem>
<listitem><emphasis>Linked Data</emphasis>: Information resource(s) encapsulating Structured Data expressed in RDF.
</listitem>
<listitem><emphasis>non-information resource</emphasis>: Any resource that is not an information resource (i.e., not Web transportable in basic form).
 Structured data resource (see below) is a more accurate and preferable term.
</listitem>
<listitem><emphasis>Semantic Data-Web</emphasis>: Web of Linked Data.
</listitem>
<listitem><emphasis>structured data</emphasis>: Data organized into semantic chunks or entities, with similar entities grouped together in relations or classes, and presented in a patterned manner.
</listitem>
<listitem><emphasis>structured data resource</emphasis>: A Web accessible container of structured data representing physical and abstract entities.
</listitem>
<listitem><emphasis>structured data source</emphasis>: A repository of structured data.
</listitem>
<listitem><emphasis>URI (Uniform Resource Identifier )</emphasis>: An Internet naming syntax which identifies a resource.
 The resource may be abstract and consequently not dereferenceable.
</listitem>
<listitem><emphasis>URL (Uniform Resource Locator)</emphasis>: An Internet naming syntax, which specifies both the identity and location of a physical, dereferenceable Web information resource.
 Although URLs and URIs share the same syntax, a URI specifies only the identity of a resource.
</listitem>
<listitem><emphasis>Web information resource</emphasis>: An entity of interest, which both exists in some form and is accessible on the World Wide Web.</listitem>
</itemizedlist><para> </para>
<bridgehead class="http://www.w3.org/1999/xhtml:h2"> Notes</bridgehead>
<ulink url="">
<para> </para>
<orderedlist spacing="compact"><listitem>Reiterating our earlier point, the URL identifies the resource, not its representations.
 <ulink url="#BodyNote1">return</ulink> <ulink url="">
 </ulink></listitem>
<listitem>Some Semantic Web (SemWeb) practitioners have argued in favor of using the URI format to distinguish between requests for document resources (also sometimes termed as information resources) belonging to the Document Web, and Data Sources, i.e., physical or abstract RDF entities (also sometimes referred to as non-information resources) belonging to the Data Web.
 (The terms information resource and non-information resource are disliked by many and have generated a good deal of debate.) With this so-called &#39;hash vs.
 slash&#39; URI convention, the presence of a fragment identifier (a hash URI, using the &quot;#&quot;) is taken to mean that a data source (entity) is being referenced; the absence of a fragment identifier (a slash URI, not using the &quot;#&quot;) implies a document resource is being referenced.
 <ulink url="#BodyNote2">return</ulink></listitem>
</orderedlist><bridgehead class="http://www.w3.org/1999/xhtml:h2"> Bibliography</bridgehead>
<itemizedlist mark="bullet" spacing="compact"><listitem><ulink url="OpenLink">OpenLink</ulink> Software: Virtuoso Linked Data Views - Getting Started Guide </listitem>
<listitem>T.
 Berners-Lee: Linked Data </listitem>
<listitem>C.
 Bizer et al.: How to Publish Linked Data on the Web </listitem>
<listitem>L.
 Sauermann et al.: Cool URIs for the Semantic Web </listitem>
<listitem>P.
 Hayes: In Defence of Ambiguity </listitem>
<listitem>R.
 Cyganiak: Debugging Semantic Web Sites With cURL </listitem>
<listitem>W3C: Dereferencing HTTP URIs </listitem>
<listitem>W3C: What do HTTP URIs Identify? </listitem>
<listitem>W3C: What URIs Identify </listitem>
<listitem>W3C: [httpRange-14] Resolved </listitem>
<listitem>W3C: Best Practice Recipes for Publishing RDF Vocabularies </listitem>
<listitem>Wikipedia: Using HTTP URIs to identify abstract resources </listitem>
<listitem>B.
 Krishnamurthy et al.: Key Differences between HTTP/1.0 and HTTP/1.1 </listitem>
<listitem>R.
 Fielding et al.: RFC2616 - HyperText Transfer Protocol - HTTP/1.1 </listitem>
<listitem>K.
 Holtman &amp; A.
 Mutz: RFC2295 - Transparent Content Negotiation in HTTP</listitem>
</itemizedlist><bridgehead class="http://www.w3.org/1999/xhtml:h2"> See Also</bridgehead>
<itemizedlist mark="bullet" spacing="compact"><listitem><ulink url="VirtEvaluatorGuideLinkedDataDeployment">Evaluator Guide for Linked Data Deployment</ulink> </listitem>
<listitem><ulink url="VirtLinkedDataDeploymentTutorialDOAP">Linked Data Deployment DOAP Tutorial</ulink></listitem>
</itemizedlist><bridgehead class="http://www.w3.org/1999/xhtml:h2"> Change History</bridgehead>
<para>1.0 Initial draft (K.
 Idehen / C.
 Blakeley, 14 Aug 2007)</para>
<para>1.1 Additions covering transparent content negotiation (C.
 Blakeley, 07 Nov 2007)</para>
<para>1.2 ???</para>
<para>1.3 Edit and polish (T.
 Thibodeau, K.
 Idehen, etc., Nov 2008) </para>
</ulink></section></docbook>