RDF : javascript, xsl stylesheets
A few notes:
I've implemented a javascript library to parse RDF (I love re-inventing the wheel, it's always interesting to learn how softwares and algorithms are working ). The RDF syntax is still not fully implemented (e.g. it don't support xml:lang, parseType=Literal, etc...)

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/************************** | |
* | |
* RDF library in Javascript | |
* Author: Pierre Lindenbaum | |
* plindenbaum@yahoo.fr | |
* http://plindenbaum.blogspot.com | |
*/ | |
/** | |
* A RDF Resource | |
*/ | |
function Resource(uri) | |
{ | |
this.uri=uri; | |
} | |
Resource.prototype.isLiteral=function() | |
{ | |
return false; | |
}; | |
Resource.prototype.isResource=function() | |
{ | |
return true; | |
}; | |
Resource.prototype.compareTo=function(other) | |
{ | |
if(!other.isResource()) return -1; | |
return this.uri.localeCompare(other.uri); | |
}; | |
Resource.prototype.toString=function() | |
{ | |
if(this.isAnonId()) return this.uri; | |
return "<"+this.uri+">"; | |
}; | |
Resource.prototype.isAnonId=function() | |
{ | |
return this.uri.substr(0,2)=="_:"; | |
}; | |
/** | |
* A RDF Literal | |
*/ | |
function Literal(content,type,lang) | |
{ | |
this.content=content; | |
this.dataType=null; | |
this.lang=null; | |
} | |
Literal.prototype.isLiteral=function() | |
{ | |
return true; | |
}; | |
Literal.prototype.isResource=function() | |
{ | |
return false; | |
}; | |
Literal.prototype.toString=function() | |
{ | |
return "\""+this.content+"\"";//TODO escape this ! | |
}; | |
Literal.prototype.compareTo=function(other) | |
{ | |
if(!other.isLiteral()) return 1; | |
var i= this.content.localeCompare(other.content); | |
if(i!=0) return i; | |
}; | |
/** | |
* A RDF Statement (S,P,V) | |
*/ | |
function Statement( subject, predicate,value) | |
{ | |
this.subject=subject; | |
this.predicate=predicate; | |
this.value=value; | |
} | |
Statement.prototype.isLiteral=function() | |
{ | |
return this.value.isLiteral(); | |
}; | |
Statement.prototype.isResource=function() | |
{ | |
return this.value.isResource(); | |
}; | |
Statement.prototype.compareTo=function(other) | |
{ | |
var i= this.subject.compareTo(other.subject); | |
if(i!=0) return i; | |
i= this.predicate.compareTo(other.predicate); | |
if(i!=0) return i; | |
return this.value.compareTo(other.value); | |
}; | |
Statement.prototype.toString=function() | |
{ | |
return ""+this.subject+" "+this.predicate+" "+this.value+" ."; | |
}; | |
/** | |
* A RDF store | |
* statements are stored in a sorted array | |
*/ | |
function RDFStore() | |
{ | |
this.statements= new Array(); | |
} | |
RDFStore.prototype.clear= function() | |
{ | |
return this.statements.slice(0,this.statements.length); | |
}; | |
RDFStore.prototype.size= function() | |
{ | |
return this.statements.length; | |
}; | |
RDFStore.prototype.lowerBound= function(stmt) | |
{ | |
var first=0; | |
var len = this.size(); | |
while (len > 0) | |
{ | |
var half = (len / 2) | 0; //hack , cast to int | |
var middle = first + half; | |
var x= this.at(middle); | |
if(x.compareTo(stmt)<0) | |
{ | |
first = middle + 1; | |
len -= half + 1; | |
} | |
else | |
{ | |
len = half; | |
} | |
} | |
return first; | |
}; | |
RDFStore.prototype.at= function(index) | |
{ | |
return this.statements[index]; | |
}; | |
RDFStore.prototype.add= function(stmt) | |
{ | |
var i= this.lowerBound(stmt); | |
if(i<this.size()) | |
{ | |
if( this.at(i).compareTo(stmt) == 0) return false; | |
} | |
this.statements.splice(i,0,stmt); | |
return true; | |
} | |
RDFStore.prototype.contains= function(stmt) | |
{ | |
var i= this.lowerBound(stmt); | |
return i<this.size() && this.at(i).compareTo(stmt) == 0; | |
}; | |
RDFStore.prototype.remove= function(stmt) | |
{ | |
var i= this.lowerBound(stmt); | |
if(i<this.size()) | |
{ | |
if( this.at(i).compareTo(stmt) != 0) return; | |
} | |
this.statements.splice(i,1); | |
}; | |
/** | |
* find a given statement, arguments can be null to allow all the nodes | |
* this method should be improved as all statements are sorted, access | |
* should be straightforward | |
*/ | |
RDFStore.prototype.filter= function(s,p,v) | |
{ | |
var store= new RDFStore(); | |
for(var i=0;i< this.size();++i) | |
{ | |
var stmt= this.at(i); | |
if(s!=null && s.compareTo(stmt.subject)!=0) continue; | |
if(p!=null && p.compareTo(stmt.predicate)!=0) continue; | |
if(v!=null && v.compareTo(stmt.value)!=0) continue; | |
store.add(stmt); | |
} | |
return store; | |
}; | |
RDFStore.prototype.parse=function(dom) | |
{ | |
} | |
/** | |
* parse a DOM document and extract the Statements | |
* parseType="Literal" not implemented | |
*/ | |
function DOM4RDF() | |
{ | |
} | |
var ANONID=0; | |
DOM4RDF.prototype.parse=function(dom,store) | |
{ | |
this.store = (typeof(store) != 'undefined' ? store : null ); | |
var tmp= this.parseRDF(dom.documentElement); | |
this.store=null; | |
return tmp; | |
}; | |
/** creates an anonymous ID */ | |
DOM4RDF.prototype.createAnonId=function() | |
{ | |
return new Resource("_:"+(++ ANONID)); | |
}; | |
/** parse a rdf:RDF element */ | |
DOM4RDF.prototype.parseRDF=function(root) | |
{ | |
if(root==null) throw "null root"; | |
if(!this.isA(root, RDF.NS, "RDF")) throw "Root is not rdf:RDF"; | |
//loop over children of rdf:RDF | |
for(var n1= root.firstChild; | |
n1!=null;n1=n1.nextSibling) | |
{ | |
switch(n1.nodeType) | |
{ | |
case 1: | |
{ | |
this.parseResource(n1); | |
break; | |
} | |
case 3: | |
case 4: | |
{ | |
this.checkNodeIsEmpty(n1); | |
break; | |
} | |
case 7: | |
{ | |
this.warning(n1, "Found Processing instruction under "+root.nodeName); | |
break; | |
} | |
case 8:break; | |
default: throw "Node type not handled : "+n1.nodeType; | |
} | |
} | |
return this.store; | |
}; | |
/** return wether this node a a rdf:(abou|ID|nodeId) */ | |
DOM4RDF.prototype.isAnonymousResource=function(rsrc) | |
{ | |
var att= rsrc.getAttributeNodeNS(RDF.NS, "about"); | |
if(att!=null) return false; | |
att= rsrc.getAttributeNodeNS(RDF.NS, "ID"); | |
if(att!=null) return false; | |
att= rsrc.getAttributeNodeNS(RDF.NS, "nodeID"); | |
if(att!=null) return false; | |
return true; | |
}; | |
/** returns a URI for an Resource element */ | |
DOM4RDF.prototype.getResourceURI=function( root) | |
{ | |
var subject=null; | |
if(root.hasAttributes()) | |
{ | |
for(var i=0;i< root.attributes.length;++i) | |
{ | |
var att=root.attributes[i]; | |
if( RDF.NS != att.namespaceURI ) continue; | |
if(att.localName == "about") | |
{ | |
if(subject!=null) throw "subject id defined twice"; | |
subject= new Resource(att.value); | |
} | |
else if(att.localName=="ID") | |
{ | |
if(subject!=null) throw "subject id defined twice"; | |
var val= att.value; | |
if(!val.startsWith("#")) val="#"+val; | |
subject= new Resource(this.getBase(root)+val); | |
} | |
else if(att.localName == "nodeID" ) | |
{ | |
if(subject!=null) throw "subject id defined twice"; | |
subject= new Resource("_:"+att.value); | |
//uri= URI.create(getBase(root)+att.value); | |
} | |
} | |
} | |
if(subject==null) subject= this.createAnonId(); | |
return subject; | |
}; | |
/** parse everything under rdf:RDF | |
* @return the URI of the resource | |
*/ | |
DOM4RDF.prototype.parseResource=function(root) | |
{ | |
var subject= this.getResourceURI(root); | |
if(root.hasAttributes()) | |
{ | |
for(var i=0;i< root.attributes.length;++i) | |
{ | |
var att=root.attributes[i]; | |
if(RDF.NS == att.namespaceURI) | |
{ | |
if(att.localName=="about" || | |
att.localName=="nodeID" || | |
att.localName=="ID" | |
) | |
{ | |
continue; | |
} | |
else if(att.localName=="resource") | |
{ | |
throw "should not contains rdf:resource"; | |
} | |
else | |
{ | |
throw "rdf:* node supported"; | |
} | |
} | |
else if(att.prefix=="xmlns") | |
{ | |
//ignore | |
} | |
else | |
{ | |
if(att.namespaceURI==null) | |
{ | |
throw "No NamespaceURI associated with "+att.nodeName; | |
} | |
this.foundStatement( | |
subject, | |
new Resource(att.namespaceURI+att.localName), | |
new Literal(att.value) | |
); | |
} | |
} | |
} | |
if(!this.isA(root, RDF.NS, "Resource")) | |
{ | |
if(root.namespaceURI==null) | |
{ | |
throw "No NamespaceURI associated with "+root.nodeName; | |
} | |
this.foundStatement( | |
subject, | |
new Resource(RDF.NS+"type"), | |
new Resource(root.namespaceURI+root.localName) | |
); | |
} | |
this.parseResourceChildren(root, subject); | |
return subject; | |
}; | |
DOM4RDF.prototype.isA=function(node,ns,localName) | |
{ | |
return node.namespaceURI==ns && node.localName==localName; | |
}; | |
/** check a node contains only a blank stuff */ | |
DOM4RDF.prototype.checkNodeIsEmpty=function( n1) | |
{ | |
if(n1.nodeValue.replace(/^\s+|\s+$/g, "").length!=0) | |
{ | |
throw "Found not whitespace content under "+n1.parentNode.nodeName; | |
} | |
return true; | |
}; | |
/** parse everything under a resource element */ | |
DOM4RDF.prototype.parseResourceChildren=function(root, subjectURI) | |
{ | |
for(var n1= root.firstChild; | |
n1!=null; | |
n1=n1.nextSibling) | |
{ | |
switch(n1.nodeType) | |
{ | |
case 1: | |
{ | |
this.parseProperty(n1,subjectURI); | |
break; | |
} | |
case 3:case 4: | |
{ | |
this.checkNodeIsEmpty(n1); | |
break; | |
} | |
case 7: | |
{ | |
this.warning(n1, "Found Processing instruction under "+root.nodeName); | |
break; | |
} | |
case 8:break; | |
default:throw "invalid node type"; | |
} | |
} | |
}; | |
/** return the xml:lang of the node or null */ | |
DOM4RDF.prototype.getLang=function( root) | |
{ | |
if(root==null) return null; | |
if( root.nodeType==1 && root.hasAttributes()) | |
{ | |
var att= root.getAttributeNodeNS(XML.NS, "lang"); | |
if(att!=null) return att.value; | |
} | |
return this.getLang(root.parentNode); | |
}; | |
/** parse everything under rdf:RDF */ | |
DOM4RDF.prototype.parseProperty=function( property, subject) | |
{ | |
var parseTypeNode= property.getAttributeNodeNS(RDF.NS, "parseType"); | |
var dataTypeNode = property.getAttributeNodeNS(RDF.NS, "dataType"); | |
var dataType= (dataTypeNode==null?null:dataTypeNode.value); | |
var parseType = parseTypeNode!=null?parseTypeNode.value:null; | |
if(property.namespaceURI==null) | |
{ | |
throw "no namespaceURI for "+property.tagName; | |
} | |
var predicate= new Resource(property.namespaceURI+property.localName); | |
if(predicate==null) | |
{ | |
throw "Cannot parse URI of this predicate"; | |
} | |
/** default parse type */ | |
if(parseType==null) | |
{ | |
var rsrc= property.getAttributeNodeNS(RDF.NS, "resource"); | |
if(!property.hasChildNodes()) | |
{ | |
if(rsrc==null) | |
{ | |
//strange behavior of DOM parser. <tag></tag> is same as <tag/> ??! | |
this.foundStatement(subject, predicate,new Literal("")); | |
//throw new InvalidXMLException(property,"missing rdf:resource"); | |
} | |
else | |
{ | |
this.foundStatement(subject, predicate, new Resource(rsrc.value)); | |
} | |
} | |
else | |
{ | |
if(rsrc!=null) throw "rdf:resource is present and element has children"; | |
if(predicate.uri == (RDF.NS+"type")) throw "rdf:type expected in an empty element"; | |
var count = 0; | |
var firstChild=null; | |
for(var n1=property.firstChild;n1!=null;n1=n1.nextSibling) | |
{ | |
if(n1.nodeType!=1) continue; | |
count++; | |
if(firstChild==null) firstChild=n1; | |
} | |
switch(count) | |
{ | |
case 0: var L= new Literal( property.textContent); | |
L.dataType= dataType; | |
L.lang= this.getLang(property); | |
this.foundStatement(subject, predicate,L ); | |
break; | |
case 1: var value= this.parseResource(firstChild); | |
this.foundStatement(subject, predicate,value); | |
break; | |
default: throw "illegal number of element under."; | |
} | |
} | |
} | |
else if( parseType == "Literal" ) | |
{ | |
var buff= ""; | |
for(var n1=property.firstChild;n1!=null;n1=n1.nextSibling) | |
{ | |
switch(n1.nodeType) | |
{ | |
case 3: | |
case 4: | |
{ | |
buff += n1.textContent; | |
break; | |
} | |
case 1: | |
{ | |
//TODO | |
break; | |
} | |
default: throw "node type unsupported "+n1.nodeType; | |
} | |
} | |
if(subject!=null && predicate!=null && buff!=null) | |
{ | |
var L2= new Literal(buff); | |
L2.dataType= RDF.NS+"XMLLiteral"; | |
L2.lang= this.getLang(property); | |
this.foundStatement(subject,predicate,L2); | |
} | |
} | |
else if(parseType=="Resource") | |
{ | |
var rsrc= this.createAnonId(); | |
if(subject!=null && predicate!=null) | |
{ | |
this.foundStatement(subject,predicate,rsrc); | |
} | |
for(var n1=property.firstChild;n1!=null;n1=n1.nextSibling) | |
{ | |
switch(n1.nodeType) | |
{ | |
case 3: | |
{ | |
this.checkNodeIsEmpty(n1); | |
break; | |
} | |
case 1: | |
{ | |
this.parseProperty(n1, rsrc); | |
break; | |
} | |
case 8:break; | |
default: this.warning(n1, "unsupported node type");break; | |
} | |
} | |
} | |
else if(parseType=="Collection") | |
{ | |
var list= new Array(); | |
for(var n1=property.firstChild;n1!=null;n1=n1.nextSibling) | |
{ | |
switch(n1.nodeType) | |
{ | |
case 8:break; | |
case 3: | |
{ | |
this.checkNodeIsEmpty(n1); | |
break; | |
} | |
case 1: | |
{ | |
var r= this.parseResource(n1); | |
list.push(r); | |
break; | |
} | |
default: this.warning(n1, "unsupported node type");break; | |
} | |
} | |
if(list.length==0) | |
{ | |
this.warning(property,"Empty list"); | |
} | |
else | |
{ | |
var prevURI= this.createAnonId(); | |
if(subject!=null && predicate!=null) | |
{ | |
this.foundStatement(subject, predicate,prevURI); | |
} | |
for(var i=0;i< list.length;++i) | |
{ | |
if(i+1==list.length) | |
{ | |
this.foundStatement(prevURI,new Resource(RDF.NS+"first"), list[i]); | |
this.foundStatement(prevURI,new Resource(RDF.NS+"rest"), new Resource(RDF.NS+"nil")); | |
} | |
else | |
{ | |
var newURI= this.createAnonId(); | |
this.foundStatement(prevURI,new Resource(RDF.NS+"first"), list[i]); | |
this.foundStatement(prevURI,new Resource(RDF.NS+"rest"), newURI); | |
prevURI=newURI; | |
} | |
} | |
} | |
} | |
else | |
{ | |
throw "illegal rdf:parseType:"+parseType; | |
} | |
}; | |
/** get the BASE url of the document */ | |
DOM4RDF.prototype.getBase=function( n) | |
{ | |
var s="TODO";//n.ownerDocument.getBaseURI(); | |
if(s==null) throw "document has not xml:base"; | |
return new Resource(s); | |
}; | |
/** | |
* Called when a Statement was found. User can override this method. | |
* Default: does nothing | |
* @param subject | |
* @param property | |
* @param value | |
* @param dataType | |
* @param lang | |
*/ | |
DOM4RDF.prototype.foundStatement=function(subject,property,value) | |
{ | |
if(this.store!=null) this.store.add(new Statement(subject,property,value)); | |
}; | |
DOM4RDF.prototype.warning=function(node,message) | |
{ | |
//logMsg("Warning " +message); | |
}; | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<window id="xulfox" | |
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" | |
title="Test RDF"> | |
<script src="utils.js"></script> | |
<script src="rdf.js"></script> | |
<script><![CDATA[ | |
var documentBuilder=new DOMParser(); | |
function parseRDF(textarea) | |
{ | |
var e=document.getElementById("label.message"); | |
var xmlDoc= documentBuilder.parseFromString(textarea.value,"text/xml"); | |
if(xmlDoc==null || xmlDoc.documentElement.localName=="parsererror") | |
{ | |
e.value= "Error"+xmlDoc.documentElement.textContent; | |
} | |
else | |
{ | |
try | |
{ | |
var dom4rdf= new DOM4RDF(); | |
var store= dom4rdf.parse(xmlDoc,new RDFStore()); | |
var treechildren= document.getElementById("statements"); | |
var n= treechildren.firstChild; | |
while(n!=null) | |
{ | |
if(n.nodeType==1 && n.localName=="treeitem") | |
{ | |
var n2=n; | |
n=n.nextSibling; | |
treechildren.removeChild(n2); | |
continue; | |
} | |
else | |
{ | |
n=n.nextSibling; | |
} | |
} | |
for(n=0;n< store.size();++n) | |
{ | |
var stmt= store.at(n); | |
var treeitem = document.createElementNS(XUL.NS,"treeitem"); | |
var treerow = document.createElementNS(XUL.NS,"treerow"); | |
treeitem.appendChild(treerow); | |
var listS = document.createElementNS(XUL.NS,"treecell"); | |
listS.setAttribute("label", stmt.subject.toString()); | |
var listP = document.createElementNS(XUL.NS,"treecell"); | |
listP.setAttribute("label", stmt.predicate.toString()); | |
var listO = document.createElementNS(XUL.NS,"treecell"); | |
listO.setAttribute("label", stmt.value.toString()); | |
treerow.appendChild(listS); | |
treerow.appendChild(listP); | |
treerow.appendChild(listO); | |
treechildren.appendChild(treeitem); | |
} | |
e.value=""; | |
} | |
catch(err) | |
{ | |
e.value="RDF:Error "+err; | |
} | |
} | |
e.tooltiptext = e.value; | |
} | |
]]></script> | |
<dialogheader title="Test For RDF" description="Pierre Lindenbaum plindenbaum yahoo.fr"/> | |
<hbox flex="1"> | |
<vbox flex="1"> | |
<groupbox id="create.list.panel" flex="1"> | |
<caption label="Create Your RDF"/> | |
<textbox multiline="true" emptytext="RDF as XML" value="<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"></rdf:RDF>" flex="1" onkeyup="parseRDF(this);"/> | |
<hbox flex="1"> | |
<label width="100%" id="label.message" value="" style="font-size:12pt;color:red;" flex="1" crop="end"/> | |
</hbox> | |
</groupbox> | |
</vbox> | |
<vbox flex="1"> | |
<groupbox id="create.list.panel" flex="1"> | |
<caption label="Statements"/> | |
<tree flex="1" rows="10"> | |
<treecols> | |
<treecol label="Subject" flex="1" /> | |
<splitter class="tree-splitter"/> | |
<treecol label="Predicate" flex="1" /> | |
<splitter class="tree-splitter"/> | |
<treecol label="Object" flex="1" /> | |
</treecols> | |
<treechildren id="statements"> | |
</treechildren> | |
</tree> | |
</groupbox> | |
</vbox> | |
</hbox> | |
</window> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
String.prototype.trim = function() { | |
try { | |
return this.replace(/^\s+|\s+$/g, ""); | |
} catch(e) { | |
return this; | |
} | |
}; | |
String.prototype.startsWith = function(s) | |
{ | |
if(s==null || this.length < s.length) return false; | |
return this.substr(0,s.length) == s; | |
}; | |
function $(id) | |
{ | |
var e = document.getElementById(id); | |
return e; | |
} | |
var XUL={NS:"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"}; | |
var HTML={NS:"http://www.w3.org/1999/xhtml"}; | |
var RDF={NS:"http://www.w3.org/1999/02/22-rdf-syntax-ns#"}; | |
var RDFS={NS:"http://www.w3.org/2000/01/rdf-schema#"}; | |
var XLINK={NS:"http://www.w3.org/1999/xlink"}; | |
var SVG={NS:"http://www.w3.org/2000/svg"}; | |
var DC={NS:"http://purl.org/dc/elements/1.1/"}; | |
var XML={NS:"http://www.w3.org/XML/1998/namespace"}; | |
var XMLNS={NS:"http://www.w3.org/2000/xmlns/"}; |
I've also created 3 XSLT stylesheets transforming RDF to ....
- N3:xsltproc rdf2n3.xsl http://www.w3.org/TR/rdf-syntax-grammar/example12.rdf
<http://www.w3.org/TR/rdf-syntax-grammar> <http://purl.org/dc/elements/1.1/title> "RDF/XML Syntax Specification (Revised)" .
<http://www.w3.org/TR/rdf-syntax-grammar> <http://example.org/stuff/1.0/editor> <_:anodeid2245696> .
<_:anodeid2245696> <http://example.org/stuff/1.0/fullName> "Dave Beckett" .
<_:anodeid2245696> <http://example.org/stuff/1.0/homePage> <http://purl.org/net/dajobe/> . - rdf:Statement:xsltproc rdf2rdf.xsl http://www.w3.org/TR/rdf-syntax-grammar/example12.rdf
<?xml version="1.0"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Statement>
<rdf:subject rdf:resource="http://www.w3.org/TR/rdf-syntax-grammar"/>
<rdf:predicate rdf:resource="http://purl.org/dc/elements/1.1/title"/>
<rdf:object>RDF/XML Syntax Specification (Revised)</rdf:object>
</rdf:Statement>
<rdf:Statement>
<rdf:subject rdf:resource="http://www.w3.org/TR/rdf-syntax-grammar"/>
<rdf:predicate rdf:resource="http://example.org/stuff/1.0/editor"/>
<rdf:object rdf:resource="_:anodeid2245620"/>
</rdf:Statement>
<rdf:Statement>
<rdf:subject rdf:resource="_:anodeid2245620"/>
<rdf:predicate rdf:resource="http://example.org/stuff/1.0/fullName"/>
<rdf:object>Dave Beckett</rdf:object>
</rdf:Statement>
<rdf:Statement>
<rdf:subject rdf:resource="_:anodeid2245620"/>
<rdf:predicate rdf:resource="http://example.org/stuff/1.0/homePage"/>
<rdf:object rdf:resource="http://purl.org/net/dajobe/"/>
</rdf:Statement>
</rdf:RDF> - SQL statements:xsltproc rdf2sql.xsl http://www.w3.org/TR/rdf-syntax-grammar/example12.rdf
create table TRIPLE IF NOT EXISTS
(
subject varchar(50) not null,
predicate varchar(50) not null,
value_is_uri enum('true','false') not null,
value varchar(50) not null //need to fix dataType and xml:lang
);
insert into TRIPLE(subject,predicate,value_is_uri,value) values ("http://www.w3.org/TR/rdf-syntax-grammar","http://purl.org/dc/elements/1.1/title","false","RDF/XML Syntax Specification (Revised)");
insert into TRIPLE(subject,predicate,value_is_uri,value) values ("http://www.w3.org/TR/rdf-syntax-grammar","http://example.org/stuff/1.0/editor","true","_:anodeid2245974");
insert into TRIPLE(subject,predicate,value_is_uri,value) values ("_:anodeid2245974","http://example.org/stuff/1.0/fullName","false","Dave Beckett");
insert into TRIPLE(subject,predicate,value_is_uri,value) values ("_:anodeid2245974","http://example.org/stuff/1.0/homePage","true","http://purl.org/net/dajobe/");
That's it
Pierre
No comments:
Post a Comment