RDF Applications with Prolog
by Bijan Parsia
|
Pages: 1, 2, 3, 4, 5, 6
DCGs Compared to XSLT
To use the transforming grammar requires a bit more
infrastructure. In this case, I wrote a predicate,
rss_to_html_list/3, which loads up an RSS 1.0 file,
invokes the grammar to generate the HTML, then writes it all to a
specified file. I could call it from a GUI front end or just package
it up in a shell or CGI script. I backtranslated the grammar into an
XSLT stylesheet. Comparing the two is instructive.
| Prolog with DCG | Comparison with XSLT |
|
Boilerplate setup, akin to
" |
rdf_register_ns(rss, 'http://purl.org/rss/1.0/'),
rdf_register_ns(dc,
'http://purl.org/dc/elements/1.1/'),
|
Namespace declarations, although two less than are necessary for the
XSLT. Equivalent to the following attributes in the xsl:stylesheet:
" |
rdf_load(Source),
rdf(Resource, rss:title, literal(Title)),
|
The first line corresponds to a command line option designating the
source document. rdf_load/1 parses the file and
creates an in-memory (in this implementation) representation
of the RDF statments that may be queried by means of
appropriate predicates (like rdf/3). An XSLT
processor would take the designated file and parse it into an
in-memory representation (typically) -- often a DOM tree --
which may be queried by means of appropriate XPath
expressions.
The second line is a query which grabs a value and binds the variable Title to it. This is roughly equivalent to
One point of interest: Binding and referencing variables in XSLT is fairly painful. It's not just that it's nastily verbose (okay, it's mainly that it's nastily verbose), but that there are lots of different rules and contexts for getting back the value. Aside from that, XSLT has a fairly straightforward "assignment" model of binding (explicit) variables. The Prolog variable is (1) structural (i.e., the variable is just a "hole" in the larger term, and (2) the variable is "two-way" (i.e., you can pass a value to the query by that variable or get one out through it). |
phrase(rss_html_list(Title), TargetHtml), tell(Target), |
First line causes the DCG to be evaluated and the result bound to TargetHtml. Second line opens the result file for writing (both of these probably fall in the scope of command line option or calling function stuff for XSLT). |
print_html(TargetHtml), told. |
<xsl:output method="html"/> print_html/1 is an |
rss_html_list(ChannelTitle) -->
page(\rss_list_head(ChannelTitle),
\rss_list_body(ChannelTitle)).
|
<xsl:template match="/">
<html>
...
</html>
</xsl:template>
|
rss_list_head(PageTitle) -->
html([title([PageTitle])]).
rss_list_body(Header) -->
{setof(Item,
rdf(Item, rdf:type, rss:item),
Items)},
html([h2(align(center),[Header]),
ul(\rss_list_items(Items))]).
|
<head>
<title>
<xsl:value-of select="$title"/>
</title>
</head>
<body>
<h2 align="center">
<xsl:value-of select="$title"/>
</h2>
<ul>
<xsl:apply-templates
select="rdf:RDF/rss:item"/>
</ul>
</body>
|
rss_list_items([First_item|Rest_of_items]) -->
html([li([\list_item_content(First_item)])]),
rss_list_items(Rest_of_items).
rss_list_items([]) --> [].
|
<xsl:template match="rdf:RDF/rss:item"> <li>...</li> </xsl:template> |
list_item_content(Item) -->
{rdf(Item,dc:description,literal(Description))},
html([\rss_link(Item),br([]),Description]).
|
...
<br/>
<xsl:value-of select="./dc:description"/>
|
rss_link(Item) -->
{rdf(Item,rss:link,literal(Link)),
rdf(Item,rss:title,literal(Title))},
html(i(a(href(Link),Title))).
|
<i> <a href="{./rss:link}"> <xsl:value-of select="./rss:title"/> </a> </i> |
Standing back and looking at the XSLT sheet right after writing it, it seemed much clearer than the DCGs. A large part of this is that I'm more accustomed to writing HTML and HTML templates with embedded code than writing DCG templates. But I'm finding that the DCGs are more helpful for thinking through the problem.
Conclusion
Since the inferences in this transformation were trivial, it doesn't involve any particularly sophisticated Prolog, and yet this is precisely the kind of everyday task many of us find ourselves doing all the time. The Semantic Web, if it's to work out, will be made up as much of the ordinary and familiar as of the exotic.
Useful Links
The Transformation Scripts
SWI-Prolog
- Home page
- Documentation
- XML/SGML support and RDF Demo
- checklist/2
- set_of/3
- DCG Rules (and phrase/2)
- File stuff (tell/1 and told)
- The module system
- html_write
- The Wiki (contains info about rdf_db)
SWI-Prolog Based RDF Applications
- The RDF Parser Demo
- RDF Schema Explorer and the associated paper