rdfparser.js
Summary
TABULATOR RDF PARSER
Version 0.1
Parser believed to be in full positive RDF/XML parsing compliance
with the possible exception of handling deprecated RDF attributes
appropriately. Parser is believed to comply fully with other W3C
and industry standards where appropriate (DOM, ECMAScript, &c.)
Author: David Sheets
SVN ID: $Id$
W3C® SOFTWARE NOTICE AND LICENSE
http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
This work (and included software, documentation such as READMEs, or
other related items) is being provided by the copyright holders under
the following license. By obtaining, using and/or copying this work,
you (the licensee) agree that you have read, understood, and will
comply with the following terms and conditions.
Permission to copy, modify, and distribute this software and its
documentation, with or without modification, for any purpose and
without fee or royalty is hereby granted, provided that you include
the following on ALL copies of the software and documentation or
portions thereof, including modifications:
1. The full text of this NOTICE in a location viewable to users of
the redistributed or derivative work.
2. Any pre-existing intellectual property disclaimers, notices, or terms and
conditions. If none exist, the W3C Software Short Notice should be
included (hypertext is preferred, text is permitted) within the body
of any redistributed or derivative code.
3. Notice of any changes or modifications to the files, including the
date changes were made. (We recommend you provide URIs to the location
from which the code is derived.)
THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT
HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR
DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS,
TRADEMARKS OR OTHER RIGHTS.
COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL
OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR
DOCUMENTATION.
The name and trademarks of copyright holders may NOT be used in
advertising or publicity pertaining to the software without specific,
written prior permission. Title to copyright in this software and any
associated documentation will at all times remain with copyright
holders.
|
Class Summary
|
| RDFParser |
Class defining an RDFParser resource object tied to an RDFStore
|
function RDFParser(store) {
RDFParser.ns = {'RDF':
"http://www.w3.org/1999/02/22-rdf-syntax-ns#",
'RDFS':
"http://www.w3.org/2000/01/rdf-schema#"}
RDFParser.nodeType = {'ELEMENT': 1, 'ATTRIBUTE': 2, 'TEXT': 3,
'CDATA_SECTION': 4, 'ENTITY_REFERENCE': 5,
'ENTITY': 6, 'PROCESSING_INSTRUCTION': 7,
'COMMENT': 8, 'DOCUMENT': 9, 'DOCUMENT_TYPE': 10,
'DOCUMENT_FRAGMENT': 11, 'NOTATION': 12}
this['frameFactory'] = function (parser, parent, element) {
return {'NODE': 1,
'ARC': 2,
'parent': parent,
'parser': parser,
'store': parser['store'],
'element': element,
'lastChild': 0,
'base': null,
'lang': null,
'node': null,
'nodeType': null,
'listIndex': 1,
'rdfid': null,
'datatype': null,
'collection': false,
'terminateFrame': function () {
if (this['collection']) {
this['node']['close']()
}
},
'addSymbol': function (type, uri) {
uri = URIjoin(uri, this['base'])
this['node'] = this['store']['sym'](uri)
this['nodeType'] = type
},
'loadTriple': function () {
if (this['parent']['parent']['collection']) {
this['parent']['parent']['node']['append'](this['node'])
}
else {
this['store']['add'](this['parent']['parent']['node'],
this['parent']['node'],
this['node'],
this['parser']['why'])
}
if (this['parent']['rdfid'] != null) {
var triple = this['store']['sym'](
URIjoin("#"+this['parent']['rdfid'],this['base']))
this['store']['add'](triple,
this['store']['sym'](
RDFParser['ns']['RDF']
+"type"),
this['store']['sym'](
RDFParser['ns']['RDF']
+"Statement"),
this['parser']['why'])
this['store']['add'](triple,
this['store']['sym'](
RDFParser['ns']['RDF']
+"subject"),
this['parent']['parent']['node'],
this['parser']['why'])
this['store']['add'](triple,
this['store']['sym'](
RDFParser['ns']['RDF']
+"predicate"),
this['parent']['node'],
this['parser']['why'])
this['store']['add'](triple,
this['store']['sym'](
RDFParser['ns']['RDF']
+"object"),
this['node'],
this['parser']['why'])
}
},
'isTripleToLoad': function () {
return (this['parent'] != null
&& this['parent']['parent'] != null
&& this['nodeType'] == this['NODE']
&& this['parent']['nodeType'] == this['ARC']
&& this['parent']['parent']['nodeType']
== this['NODE'])
},
'addNode': function (uri) {
this['addSymbol'](this['NODE'],uri)
if (this['isTripleToLoad']()) {
this['loadTriple']()
}
},
'addCollection': function () {
this['nodeType'] = this['NODE']
this['node'] = this['store']['collection']()
this['collection'] = true
if (this['isTripleToLoad']()) {
this['loadTriple']()
}
},
'addCollectionArc': function () {
this['nodeType'] = this['ARC']
},
'addBNode': function (id) {
if (id != null) {
if (this['parser']['bnodes'][id] != null) {
this['node'] = this['parser']['bnodes'][id]
} else {
this['node'] = this['parser']['bnodes'][id] = this['store']['bnode']()
}
} else { this['node'] = this['store']['bnode']() }
this['nodeType'] = this['NODE']
if (this['isTripleToLoad']()) {
this['loadTriple']()
}
},
'addArc': function (uri) {
if (uri == RDFParser['ns']['RDF']+"li") {
uri = RDFParser['ns']['RDF']+"_"+this['parent']['listIndex']++
}
this['addSymbol'](this['ARC'], uri)
},
'addLiteral': function (value) {
if (this['parent']['datatype']) { var lang = "" }
else { var lang = this['lang'] }
this['node'] = this['store']['literal'](
value, lang, this['parent']['datatype'])
this['nodeType'] = this['NODE']
if (this['isTripleToLoad']()) {
this['loadTriple']()
}
}
}
}
this['store'] = store
this['bnodes'] = {}
this['why'] = null
this.reify = false
this.forceRDF = false
this.parse = function (document, base, why) {
var children = document['childNodes']
this['cleanParser']()
if (document['nodeType'] == RDFParser['nodeType']['DOCUMENT']) {
for (var c=0; c<children['length']; c++) {
if (children[c]['nodeType']
== RDFParser['nodeType']['ELEMENT']) {
var root = children[c]
break
}
}
}
else if (document['nodeType'] == RDFParser['nodeType']['ELEMENT']) {
var root = document
}
else {
throw new Error("RDFParser: can't find root in " + base
+ ". Halting. ")
return false
}
this['why'] = why
if (!this['forceRDF']
&& root['namespaceURI'] != RDFParser['ns']['RDF']) {
throw new Error("RDFParser: " + base
+ " might not be RDF. Halting. "
+ "Parser expected either assurance"
+ " of RDF or root node with namespace"
+ " of " + RDFParser['ns']['RDF']);
return false
}
var f = this['frameFactory'](this)
f['base'] = base
f['lang'] = ''
this['parseDOM'](this['buildFrame'](f,root))
return true
}
this['parseDOM'] = function (frame) {
var elementURI = function (el) {
return el['namespaceURI'] + el['localName']
}
var dig = true
while (frame['parent']) {
var dom = frame['element']
var attrs = dom['attributes']
if (dom['nodeType']
== RDFParser['nodeType']['TEXT']) {
frame['addLiteral'](dom['nodeValue'])
}
else if (elementURI(dom)
!= RDFParser['ns']['RDF']+"RDF") {
if (frame['parent'] && frame['parent']['collection']) {
frame['addCollectionArc']()
frame = this['buildFrame'](frame,frame['element'])
frame['parent']['element'] = null
}
if (!frame['parent'] || !frame['parent']['nodeType']
|| frame['parent']['nodeType'] == frame['ARC']) {
var about =dom['getAttributeNodeNS'](
RDFParser['ns']['RDF'],"about")
var rdfid =dom['getAttributeNodeNS'](
RDFParser['ns']['RDF'],"ID")
if (about && rdfid) {
throw new Error("RDFParser: " + dom['nodeName']
+ " has both rdf:id and rdf:about."
+ " Halting. Only one of these"
+ " properties may be specified on a"
+ " node.");
}
if (about == null && rdfid) {
frame['addNode']("#"+rdfid['nodeValue'])
dom['removeAttributeNode'](rdfid)
}
else if (about == null && rdfid == null) {
var bnid = dom['getAttributeNodeNS'](
RDFParser['ns']['RDF'],"nodeID")
if (bnid) {
frame['addBNode'](bnid['nodeValue'])
dom['removeAttributeNode'](bnid)
} else { frame['addBNode']() }
}
else {
frame['addNode'](about['nodeValue'])
dom['removeAttributeNode'](about)
}
var rdftype = dom['getAttributeNodeNS'](
RDFParser['ns']['RDF'],"type")
if (RDFParser['ns']['RDF']+"Description"
!= elementURI(dom)) {
rdftype = {'nodeValue': elementURI(dom)}
}
if (rdftype != null) {
this['store']['add'](frame['node'],
this['store']['sym'](
RDFParser['ns']['RDF']+"type"),
this['store']['sym'](
URIjoin(rdftype['nodeValue'],
frame['base'])),
this['why'])
if (rdftype['nodeName']){
dom['removeAttributeNode'](rdftype)
}
}
for (var x = attrs['length']-1; x >= 0; x--) {
this['store']['add'](frame['node'],
this['store']['sym'](
elementURI(attrs[x])),
this['store']['literal'](
attrs[x]['nodeValue'],
frame['lang'],""),
this['why'])
}
}
else {
frame['addArc'](elementURI(dom))
if (this['reify']) {
var rdfid = dom['getAttributeNodeNS'](
RDFParser['ns']['RDF'],"ID")
if (rdfid) {
frame['rdfid'] = rdfid['nodeValue']
dom['removeAttributeNode'](rdfid)
}
}
var parsetype = dom['getAttributeNodeNS'](
RDFParser['ns']['RDF'],"parseType")
var datatype = dom['getAttributeNodeNS'](
RDFParser['ns']['RDF'],"datatype")
if (datatype) {
frame['datatype'] = datatype['nodeValue']
dom['removeAttributeNode'](datatype)
}
if (parsetype) {
var nv = parsetype['nodeValue']
if (nv == "Literal") {
frame['datatype']
= RDFParser['ns']['RDF']+"XMLLiteral"
frame = this['buildFrame'](frame)
frame['addLiteral'](dom)
dig = false
}
else if (nv == "Resource") {
frame = this['buildFrame'](frame,frame['element'])
frame['parent']['element'] = null
frame['addBNode']()
}
else if (nv == "Collection") {
frame = this['buildFrame'](frame,frame['element'])
frame['parent']['element'] = null
frame['addCollection']()
}
dom['removeAttributeNode'](parsetype)
}
if (attrs['length'] != 0) {
var resource = dom['getAttributeNodeNS'](
RDFParser['ns']['RDF'],"resource")
var bnid = dom['getAttributeNodeNS'](
RDFParser['ns']['RDF'],"nodeID")
frame = this['buildFrame'](frame)
if (resource) {
frame['addNode'](resource['nodeValue'])
dom['removeAttributeNode'](resource)
} else {
if (bnid) {
frame['addBNode'](bnid['nodeValue'])
dom['removeAttributeNode'](bnid)
} else { frame['addBNode']() }
}
for (var x = attrs['length']-1; x >= 0; x--) {
var f = this['buildFrame'](frame)
f['addArc'](elementURI(attrs[x]))
if (elementURI(attrs[x])
==RDFParser['ns']['RDF']+"type"){
(this['buildFrame'](f))['addNode'](
attrs[x]['nodeValue'])
} else {
(this['buildFrame'](f))['addLiteral'](
attrs[x]['nodeValue'])
}
}
}
else if (dom['childNodes']['length'] == 0) {
(this['buildFrame'](frame))['addLiteral']("")
}
}
}
dom = frame['element']
while (frame['parent']) {
var pframe = frame
while (dom == null) {
frame = frame['parent']
dom = frame['element']
}
var candidate = dom['childNodes'][frame['lastChild']]
if (candidate == null || !dig) {
frame['terminateFrame']()
if (!(frame = frame['parent'])) { break }
dom = frame['element']
dig = true
}
else if ((candidate['nodeType']
!= RDFParser['nodeType']['ELEMENT']
&& candidate['nodeType']
!= RDFParser['nodeType']['TEXT'])
|| (candidate['nodeType']
== RDFParser['nodeType']['TEXT']
&& dom['childNodes']['length'] != 1)) {
frame['lastChild']++
}
else {
frame['lastChild']++
frame = this['buildFrame'](pframe,
dom['childNodes'][frame['lastChild']-1])
break
}
}
}
}
this['cleanParser'] = function () {
this['bnodes'] = {}
this['why'] = null
}
this['buildFrame'] = function (parent, element) {
var frame = this['frameFactory'](this,parent,element)
if (parent) {
frame['base'] = parent['base']
frame['lang'] = parent['lang']
}
if (element == null
|| element['nodeType'] == RDFParser['nodeType']['TEXT']) {
return frame
}
var attrs = element['attributes']
var base = element['getAttributeNode']("xml:base")
if (base != null) {
frame['base'] = base['nodeValue']
element['removeAttribute']("xml:base")
}
var lang = element['getAttributeNode']("xml:lang")
if (lang != null) {
frame['lang'] = lang['nodeValue']
element['removeAttribute']("xml:lang")
}
for (var x = attrs['length']-1; x >= 0; x--) {
if (attrs[x]['nodeName']['substr'](0,3) == "xml") {
element['removeAttributeNode'](attrs[x])
}
}
return frame
}
}
Documentation generated by
JSDoc on Fri Jul 14 19:24:50 2006