# Errors parsing XML with rdflib.js in the browser

**URL:** <https://forum.solidproject.org/t/errors-parsing-xml-with-rdflib-js-in-the-browser/448>\
**Category:** Instructions\
**Created:** [November 7, 2018, 7:58pm UTC](https://forum.solidproject.org/t/errors-parsing-xml-with-rdflib-js-in-the-browser/448 "2018-11-07T19:58:08Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![JeffCave](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/jeffcave/32/226_2.png) [@JeffCave](https://forum.solidproject.org/u/JeffCave)\
**Post date:** [November 7, 2018, 7:58pm UTC](https://forum.solidproject.org/t/errors-parsing-xml-with-rdflib-js-in-the-browser/448/1 "2018-11-07T19:58:08Z")

</div>

I am attempting to parse a Project Gutenberg `catalog.rdf` for an in browser eReader. Therefore `rdflib.js`

My initial idea was to use SPARQL queries to extract the data, however, I can’t seem to get `rdflib.js` to execute the queries and return results (assuming I just don’t know how to wire them up).

Following the tutorials I seem to have figured out the basic use of the match routines, and have managed to get a list of the books in the catalogue. Unfortunately, when I then attempt to get the corresponding properties (title and author) they are coming back as `[object NodeList]`

Extremely stripped down example of book RDF:

```auto
<pgterms:etext rdf:ID="etext27785">
  <dc:title rdf:parseType="Literal">A Book About Lawyers</dc:title>
</pgterms:etext>

```

My code:

```auto
let store = $rdf.graph();
$rdf.parse(stm,store,baseUrl,'application/rdf+xml');
let books = store.match(undefined, types.RDF('type') , types.PGb('etext')).map(t=>t.subject);
let lib = books.map(b=>{
    let props = store.match(b, null, undefined);
    console.debug("Book: " + schema['_id']);
    props.forEach(a=>{
        console.debug(a);
    });
});

```

Resulting triple (note `object.value` is `"[object NodeList]"`):

```auto
{
  "subject": {
    "termType": "NamedNode",
    "value": "http://www.gutenberg.org/feeds/catalog.rdf#etext14600"
  },
  "predicate": {
    "termType": "NamedNode",
    "value": "http://purl.org/dc/elements/1.1/title"
  },
  "object": {
    "termType": "Literal",
    "value": "[object NodeList]",
    "datatype": {
        "termType": "NamedNode",
        "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral"
    }
  },
  "why": {
    "termType": "NamedNode",
    "value": "https://example.com/datasets/gutenberg/catalog.rdf.gz"
  }
}

```

Am I using the library incorrectly?

---

<div class="post-metadata">

**Author:** ![jeffz](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/jeffz/32/600_2.png) [@jeffz](https://forum.solidproject.org/u/jeffz)\
**Post date:** [November 8, 2018, 3:32pm UTC](https://forum.solidproject.org/t/errors-parsing-xml-with-rdflib-js-in-the-browser/448/2 "2018-11-08T15:32:43Z")

</div>

Forgive me if you know Javascript, but have you tried looking at object.value? It would appear to hold a list of titles returned by the query. So console.debug(a.object.value) instead of console.debug(a) to see it. Console commands stop after one level of dereferencing which means you won’t see the internals of objects other than the main object. If that’s not your problem, you should tell us what is the problem - what did you expect to happen and what happened instead?

---

<div class="post-metadata">

**Author:** ![JeffCave](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/jeffcave/32/226_2.png) [@JeffCave](https://forum.solidproject.org/u/JeffCave)\
**Post date:** [November 8, 2018, 5:18pm UTC](https://forum.solidproject.org/t/errors-parsing-xml-with-rdflib-js-in-the-browser/448/3 "2018-11-08T17:18:28Z")

</div>

So I double checked my setup, and my inspection of the value. Unfortunately, it still seems to be an issue; `a.object.value` does not contain a list, it contains the string value: `"[object NodeList]"`

I inspected using the console inspector, as well as modifying the test code to explicitly report the datatype.

Exact Input:

```xml
    <pgterms:etext rdf:ID="etext27785">
      <dc:publisher>&pg;</dc:publisher>
      <dc:title rdf:parseType="Literal">A Book About Lawyers</dc:title>
      <dc:creator rdf:parseType="Literal">Jeaffreson, John Cordy, 1831-1901</dc:creator>
      <pgterms:friendlytitle rdf:parseType="Literal">A Book About Lawyers by John Cordy Jeaffreson</pgterms:friendlytitle>
      <dc:language><dcterms:ISO639-2><rdf:value>en</rdf:value></dcterms:ISO639-2></dc:language>
      <dc:subject><dcterms:LCSH><rdf:value>Lawyers -- Great Britain -- Anecdotes</rdf:value></dcterms:LCSH></dc:subject>
      <dc:subject><dcterms:LCC><rdf:value>KD</rdf:value></dcterms:LCC></dc:subject>
      <dc:created><dcterms:W3CDTF><rdf:value>2009-01-12</rdf:value></dcterms:W3CDTF></dc:created>
      <pgterms:downloads><xsd:nonNegativeInteger><rdf:value>20</rdf:value></xsd:nonNegativeInteger></pgterms:downloads>
      <dc:rights rdf:resource="&lic;" />
    </pgterms:etext>

```

Code:

```javascript
let store = $rdf.graph();
$rdf.parse(stm,store,baseUrl,'application/rdf+xml');
let books = store.match(undefined, types.RDF('type') , types.PGb('etext')).map(t=>t.subject);
let lib = books.map(b=>{
    let props = store.match(b, null, undefined);
    console.debug("Book: " + schema['_id']);
    props.forEach(a=>{
	console.debug(a.predicate.value + '===' + a.object.value);
	console.debug(typeof a.object.value);
    });
});

```

Output:

```nohighlight
Book: etext27785
http://www.w3.org/1999/02/22-rdf-syntax-ns#type===http://www.gutenberg.org/rdfterms/etext
string
http://purl.org/dc/elements/1.1/publisher===Project Gutenberg
string
http://purl.org/dc/elements/1.1/title===[object NodeList]
string
...

```

**EXPECTED** :  
The text value of the title as “A Book About Lawyers”

**ACTUAL** :  
The text value of the title as “[object NodeList]”

**Notes**

1. The title is a text literal (no sub elements)
2. There is only one “title” item in the book record

---

<div class="post-metadata">

**Author:** ![jeffz](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/jeffz/32/600_2.png) [@jeffz](https://forum.solidproject.org/u/jeffz)\
**Post date:** [November 8, 2018, 11:06pm UTC](https://forum.solidproject.org/t/errors-parsing-xml-with-rdflib-js-in-the-browser/448/4 "2018-11-08T23:06:38Z")

</div>

I put pg1.rdf from the Gutenberg tarball in the same directory as this script and it works for me. Does it work for you?

```javascript
let $rdf = require('rdflib')
let a = $rdf.sym('http://www.w3.org/1999/02/22-rdf-syntax-ns#type')
let ebook = $rdf.sym('http://www.gutenberg.org/2009/pgterms/ebook')
let title = $rdf.sym('http://purl.org/dc/terms/title')

let location = './pg1.rdf'
let subj = 'file://'+location

let txt = require('fs').readFileSync( location, 'utf-8' )
let store = $rdf.graph()
$rdf.parse( txt, store, subj,'application/rdf+xml' )
let books = store.match( undefined, a, ebook )
for(b in books){
    let book = books[b].subject
    let bookTitle = store.match( book, title ,undefined)[0].object.value
    console.log(bookTitle)
}

```

---

<div class="post-metadata">

**Author:** ![jeffz](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/jeffz/32/600_2.png) [@jeffz](https://forum.solidproject.org/u/jeffz)\
**Post date:** [November 8, 2018, 11:34pm UTC](https://forum.solidproject.org/t/errors-parsing-xml-with-rdflib-js-in-the-browser/448/5 "2018-11-08T23:34:53Z")

</div>

Or, even simpler, since you know there is only one book in the file and there is only one title per book, instead of the last six lines of the code above, use:

```javascript
let book = store.any(undefined, a, ebook)
let bookTitle = store.any(book,title,undefined).value
console.log(bookTitle)

```

---

<div class="post-metadata">

**Author:** ![JeffCave](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/jeffcave/32/226_2.png) [@JeffCave](https://forum.solidproject.org/u/JeffCave)\
**Post date:** [November 8, 2018, 11:40pm UTC](https://forum.solidproject.org/t/errors-parsing-xml-with-rdflib-js-in-the-browser/448/6 "2018-11-08T23:40:23Z")

</div>

That looks node-like (`require('fs')`): is that meant to be run from the command-line?

When I run that from the command line, I’m getting an error: `async popupLogin(options)`. I think my VM defaults to an old version of node… I’ll need a bit to finish setting this test up.

---

<div class="post-metadata">

**Author:** ![jeffz](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/jeffz/32/600_2.png) [@jeffz](https://forum.solidproject.org/u/jeffz)\
**Post date:** [November 8, 2018, 11:42pm UTC](https://forum.solidproject.org/t/errors-parsing-xml-with-rdflib-js-in-the-browser/448/7 "2018-11-08T23:42:29Z")

</div>

Yes, that script runs from the command line to read the file, but you can just ignore that part and define txt as whatever you want rather than reading it from a file.

---

<div class="post-metadata">

**Author:** ![jeffz](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/jeffz/32/600_2.png) [@jeffz](https://forum.solidproject.org/u/jeffz)\
**Post date:** [November 8, 2018, 11:46pm UTC](https://forum.solidproject.org/t/errors-parsing-xml-with-rdflib-js-in-the-browser/448/8 "2018-11-08T23:46:45Z")

</div>

Just comment out the require and define the text of the RDF however you want and this should work in the browser just the same.

---

<div class="post-metadata">

**Author:** ![JeffCave](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/jeffcave/32/226_2.png) [@JeffCave](https://forum.solidproject.org/u/JeffCave)\
**Post date:** [November 9, 2018, 12:43am UTC](https://forum.solidproject.org/t/errors-parsing-xml-with-rdflib-js-in-the-browser/448/9 "2018-11-09T00:43:56Z")

</div>

OK, got it working in both browser and in node. I agree, `pg1.rdf` parses and searches cleanly, and the code you gave and the code I originally have are (basically) the same.

Is `catalogue.rdf` incorrect in some way?

---

<div class="post-metadata">

**Author:** ![jeffz](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/jeffz/32/600_2.png) [@jeffz](https://forum.solidproject.org/u/jeffz)\
**Post date:** [November 9, 2018, 12:58am UTC](https://forum.solidproject.org/t/errors-parsing-xml-with-rdflib-js-in-the-browser/448/10 "2018-11-09T00:58:36Z")

</div>

Not sure what catalogue.rdf is, but if you feed it to the same script, it should work if it uses similar terms as pg1.rdf.

---

<div class="post-metadata">

**Author:** ![JeffCave](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/jeffcave/32/226_2.png) [@JeffCave](https://forum.solidproject.org/u/JeffCave)\
**Post date:** [November 9, 2018, 1:28am UTC](https://forum.solidproject.org/t/errors-parsing-xml-with-rdflib-js-in-the-browser/448/11 "2018-11-09T01:28:34Z")

</div>

`catalogue.rdf` is one of the three files available as a [feed from PG](http://gutenberg.readingroo.ms/cache/generated/feeds/):

- today.rss
- catalog.rdf / catalog.marc
- rdf-files.tar

I chose `catalog.rdf` because it was complete, but smaller. The terms it uses are similar (as shown in the example I gave), but do not work.

Interestingly, it notice that all of the elements that try being a NodeList all have attributes associated with them. No attribute == it works ?

That’s it.

Original example:

```auto
<pgterms:etext rdf:ID="etext27785">
  <dc:title rdf:parseType="Literal">A Book About Lawyers</dc:title>
</pgterms:etext>

```

Notice the title has an attribute `parseType`. In the file you used (pg1.rdf), there is no attribute on those. If I remove the attribute from the `title` tag in `catalog` it works perfectly.

1. Is there something extra I was supposed to do to support attributes?
  - Wouldn’t surprise me

2. Is that invalid RDF syntax?
  - I’m pretty sure I saw `parseType` was standard (though I’m pretty new to RDF)

3. Is there a bug in rdflib?
  - I’ve been working to rig up an `rdflib` I can step through to help me wrap my head around what is going on

---

<div class="post-metadata">

**Author:** ![jeffz](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/jeffz/32/600_2.png) [@jeffz](https://forum.solidproject.org/u/jeffz)\
**Post date:** [November 9, 2018, 3:34am UTC](https://forum.solidproject.org/t/errors-parsing-xml-with-rdflib-js-in-the-browser/448/12 "2018-11-09T03:34:32Z")

</div>

Hmm, I don’t have catalog.rdf on hand to test at the moment but I did paste rdf:parseType=“Literal” into the dc:title tag in pg1.rdf and it still parsed fine for me.

---

<div class="post-metadata">

**Author:** ![JeffCave](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/jeffcave/32/226_2.png) [@JeffCave](https://forum.solidproject.org/u/JeffCave)\
**Post date:** [November 9, 2018, 8:58pm UTC](https://forum.solidproject.org/t/errors-parsing-xml-with-rdflib-js-in-the-browser/448/13 "2018-11-09T20:58:13Z")

</div>

“Works on my machine” 😉

There is a bug in `rdflib.js` in the way it interprets `Literals` in the browser. You didn’t see it because you are testing in `node`.

The implementation of DOMParser imported for NodeJS handles serialization of nodelists differently than the browser implementation (I almost want to say incorrectly… except I like it).

I’ve tested in Firefox and Chrome, and get the same behaviour. I want to check to make sure my fix doesn’t break node implementations before suggesting it.

Looks like the defect was created in response to [issue #75](https://github.com/linkeddata/rdflib.js/issues/75)
