[Pkg-javascript-commits] [ltx] 415/469: libxmljs backend

Jonas Smedegaard dr at jones.dk
Wed Aug 31 13:03:33 UTC 2016


This is an automated email from the git hooks/post-receive script.

js pushed a commit to branch master
in repository ltx.

commit 34b8106f85a2a8fd14f9c4c8e173a226eeb3d888
Author: Sonny Piers <sonny at fastmail.net>
Date:   Thu Nov 26 11:18:01 2015 +0100

    libxmljs backend
---
 README.md                           | 44 ++++++++++++++++++--------
 benchmark.js => benchmarks/parse.js |  6 ++--
 benchmark.js => benchmarks/write.js | 11 ++++---
 lib/Element.js                      |  3 +-
 lib/createElement.js                |  2 ++
 lib/escape.js                       | 10 ++++++
 lib/parsers/easysax.js              | 58 ----------------------------------
 lib/parsers/index.js                |  8 ++---
 lib/parsers/libxmljs.js             | 62 +++++++++++++++++++++++++++++++++++++
 lib/parsers/{sax.js => sax-js.js}   |  0
 package.json                        |  7 +++--
 test/parse-test.js                  |  7 ++++-
 12 files changed, 129 insertions(+), 89 deletions(-)

diff --git a/README.md b/README.md
index e0a3108..dc95719 100644
--- a/README.md
+++ b/README.md
@@ -5,29 +5,47 @@
 [![build status](https://img.shields.io/travis/node-xmpp/ltx/master.svg?style=flat-square)](https://travis-ci.org/node-xmpp/ltx/branches)
 [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square)](http://standardjs.com/)
 
-* *Element:* any XML Element
-* Text nodes are Strings
-* Runs on Node.js and browsers
+ltx is a fast XML builder, parser and manipulation library for JavaScript.
 
-# Documentation
+The builder is a convenient and succint API to build XML documents represented in memory as JavaScript primitives that can be serialized to XML strings. It provides a [JSX](https://facebook.github.io/jsx/) compatible API as well.
+
+The parser can parse XML documents or streams and support diffrent backends.
+
+Features:
+* Succint API to build and manipulate XML objects
+* parse XML strings
+* parse XML streams
+* multiple parser backends
+  * [sax-js](https://github.com/isaacs/sax-js)
+  * [node-xml](https://github.com/dylang/node-xml)
+  * [node-expat](https://github.com/node-xmpp/node-expat)
+  * [libxmljs](https://github.com/polotek/libxmljs)
+  * [ltx](https://github.com/node-xmpp/ltx/blob/master/lib/parsers/ltx.js) (default)
+* [JSX](https://facebook.github.io/jsx/) compatible
+
+## Install
+
+`npm install ltx`
+
+## Documentation
 
 For documentation please see http://node-xmpp.org/doc/ltx.html
 
-# Test
+## Benchmark
 
 ```
-npm install -g standard browserify
+node benchmarks/parse.js
+node benchmarks/write.js
 ```
 
-npm test
+## Test
 
+```
+npm install -g standard browserify
+npm test
+```
 
-## TODO
-
-* More documentation
-* More tests (Using [Vows](http://vowsjs.org/))
-
-# Licence
+## Licence
 
 MIT
 
diff --git a/benchmark.js b/benchmarks/parse.js
similarity index 79%
copy from benchmark.js
copy to benchmarks/parse.js
index 9038a93..9317352 100644
--- a/benchmark.js
+++ b/benchmarks/parse.js
@@ -1,11 +1,11 @@
 'use strict'
 
 var benchmark = require('benchmark')
-var ltx = require('./index')
-var parsers = require('./lib/parsers')
+var ltx = require('../index')
+var parsers = require('../lib/parsers')
 
 var XML = [
-  '<message to="foo at bar" from="bar at to" type="chat" id="foobar">',
+  '<message to="foo at bar" from="bar at foo" type="chat" id="foobar">',
   '<body>Where there is love there is life.</body>',
   '</message>'
 ].join('')
diff --git a/benchmark.js b/benchmarks/write.js
similarity index 66%
rename from benchmark.js
rename to benchmarks/write.js
index 9038a93..c8e7ed9 100644
--- a/benchmark.js
+++ b/benchmarks/write.js
@@ -1,20 +1,21 @@
 'use strict'
 
 var benchmark = require('benchmark')
-var ltx = require('./index')
-var parsers = require('./lib/parsers')
+var parsers = require('../lib/parsers')
 
 var XML = [
-  '<message to="foo at bar" from="bar at to" type="chat" id="foobar">',
+  '<message to="foo at bar" from="bar at foo" type="chat" id="foobar">',
   '<body>Where there is love there is life.</body>',
   '</message>'
 ].join('')
 
-var suite = new benchmark.Suite('parse')
+var suite = new benchmark.Suite('write')
 
 parsers.forEach(function (Parser) {
+  var parser = new Parser()
+  parser.write('<r>')
   suite.add(Parser.name, function () {
-    ltx.parse(XML, {Parser: Parser})
+    parser.write(XML)
   })
 })
 
diff --git a/lib/Element.js b/lib/Element.js
index 9b76301..fe6b6ad 100644
--- a/lib/Element.js
+++ b/lib/Element.js
@@ -20,6 +20,7 @@ function Element (name, attrs) {
   this.name = name
   this.parent = null
   this.children = []
+  this.attrs = {}
   this.setAttrs(attrs)
 }
 
@@ -95,8 +96,6 @@ Element.prototype.getXmlns = function () {
 }
 
 Element.prototype.setAttrs = function (attrs) {
-  this.attrs = {}
-
   if (typeof attrs === 'string') {
     this.attrs.xmlns = attrs
   } else if (attrs) {
diff --git a/lib/createElement.js b/lib/createElement.js
index 44abdad..f9e321c 100644
--- a/lib/createElement.js
+++ b/lib/createElement.js
@@ -1,5 +1,7 @@
 'use strict'
 
+// JSX compatible
+
 var Element = require('./Element')
 
 module.exports = function createElement (name, attrs /*, child1, child2, ...*/) {
diff --git a/lib/escape.js b/lib/escape.js
index b1eec5b..7fe2165 100644
--- a/lib/escape.js
+++ b/lib/escape.js
@@ -15,3 +15,13 @@ exports.escapeXMLText = function escapeXMLText (s) {
     .replace(/</g, '<')
     .replace(/>/g, '>')
 }
+
+exports.unescapeXML = function unescapeXML (s) {
+  return s
+    .replace(/\&(amp|#38);/g, '&')
+    .replace(/\&(lt|#60);/g, '<')
+    .replace(/\&(gt|#62);/g, '>')
+    .replace(/\&(quot|#34);/g, '"')
+    .replace(/\&(apos|#39);/g, "'")
+    .replace(/\&(nbsp|#160);/g, '\n')
+}
diff --git a/lib/parsers/easysax.js b/lib/parsers/easysax.js
deleted file mode 100644
index fa3ab63..0000000
--- a/lib/parsers/easysax.js
+++ /dev/null
@@ -1,58 +0,0 @@
-'use strict'
-
-var inherits = require('inherits')
-var EventEmitter = require('events').EventEmitter
-var Easysax = require('easysax')
-
-/**
- * FIXME: This SAX parser cannot be pushed to!
- */
-module.exports = SaxEasysax
-inherits(SaxEasysax, EventEmitter)
-
-function SaxEasysax () {
-  EventEmitter.call(this)
-  this.parser = new Easysax()
-
-  var self = this
-
-  this.parser.on('startNode', function (name, attr, uq) {
-    attr = attr()
-
-    if (attr === false) {
-      self.emit('error', 'attr char')
-      return false
-    }
-
-    for (var k in attr) {
-      attr[k] = uq(attr[k])
-    }
-
-    self.emit('startElement', name, attr)
-  })
-  this.parser.on('endNode', function (name) {
-    self.emit('endElement', name)
-  })
-  this.parser.on('textNode', function (str, uq) {
-    self.emit('text', uq(str))
-  })
-  this.parser.on('cdata', function (str) {
-    self.emit('text', str)
-  })
-  this.parser.on('error', function (e) {
-    self.emit('error', e)
-  })
-  // TODO: other events, esp. entityDecl (billion laughs!)
-
-  var sbuffer = ''
-
-  this.write = function (data) {
-    sbuffer += typeof data !== 'string' ? data.toString() : data
-  }
-
-  this.end = function (data) {
-    sbuffer += typeof data !== 'string' ? data.toString() : data
-    this.parser(sbuffer)
-    sbuffer = ''
-  }
-}
diff --git a/lib/parsers/index.js b/lib/parsers/index.js
index 694da5f..e148bc5 100644
--- a/lib/parsers/index.js
+++ b/lib/parsers/index.js
@@ -1,11 +1,11 @@
 'use strict'
 
 module.exports = [
-  // 'easysax',
-  'ltx',
-  'node-expat',
+  'sax-js',
   'node-xml',
-  'sax'
+  'libxmljs',
+  'node-expat',
+  'ltx'
 ].map(function (name) {
   return require('./' + name)
 })
diff --git a/lib/parsers/libxmljs.js b/lib/parsers/libxmljs.js
new file mode 100644
index 0000000..8f06c2f
--- /dev/null
+++ b/lib/parsers/libxmljs.js
@@ -0,0 +1,62 @@
+'use strict'
+
+var inherits = require('inherits')
+var EventEmitter = require('events').EventEmitter
+var libxmljs = require('libxmljs')
+
+function SaxLibxmljs () {
+  EventEmitter.call(this)
+  this.parser = new libxmljs.SaxPushParser()
+
+  var that = this
+
+  this.parser.on('startElementNS', function (name, attrs, prefix, uri, nss) {
+    var a = {}
+    attrs.forEach(function (attr) {
+      var name = attr[0]
+      if (attr[1]) name = attr[1] + ':' + name
+      a[name] = attr[3]
+    })
+    nss.forEach(function (ns) {
+      var name = 'xmlns'
+      if (ns[0] !== null) {
+        name += (':' + ns[0])
+      }
+      a[name] = ns[1]
+    })
+    that.emit('startElement', (prefix ? prefix + ':' : '') + name, a)
+  })
+
+  this.parser.on('endElementNS', function (name, prefix) {
+    that.emit('endElement', (prefix ? prefix + ':' : '') + name)
+  })
+
+  this.parser.on('characters', function (str) {
+    that.emit('text', str)
+  })
+
+  this.parser.on('cadata', function (str) {
+    that.emit('text', str)
+  })
+
+  this.parser.on('error', function (err) {
+    that.emit('error', err)
+  })
+}
+
+inherits(SaxLibxmljs, EventEmitter)
+
+SaxLibxmljs.prototype.write = function (data) {
+  if (typeof data !== 'string') {
+    data = data.toString()
+  }
+  this.parser.push(data)
+}
+
+SaxLibxmljs.prototype.end = function (data) {
+  if (data) {
+    this.write(data)
+  }
+}
+
+module.exports = SaxLibxmljs
diff --git a/lib/parsers/sax.js b/lib/parsers/sax-js.js
similarity index 100%
rename from lib/parsers/sax.js
rename to lib/parsers/sax-js.js
diff --git a/package.json b/package.json
index 5b3d25c..89fce14 100644
--- a/package.json
+++ b/package.json
@@ -29,6 +29,7 @@
   "license": "MIT",
   "engine": "node",
   "scripts": {
+    "prepublish": "npm run bundle",
     "preversion": "npm test",
     "bundle": "browserify -s ltx index.js -o bundle.js",
     "unit": "vows --spec",
@@ -40,11 +41,11 @@
   },
   "devDependencies": {
     "benchmark": "^1.0.0",
-    "easysax": "^0.1.14",
+    "libxmljs": "^0.16.1",
     "microtime": "^2.0.0",
-    "node-expat": "^2.3.10",
+    "node-expat": "^2.3.12",
     "node-xml": "^1.0.2",
-    "sax": "^1.1.2",
+    "sax": "^1.1.4",
     "vows": "^0.8.1"
   }
 }
diff --git a/test/parse-test.js b/test/parse-test.js
index 82428ac..a0a7c98 100644
--- a/test/parse-test.js
+++ b/test/parse-test.js
@@ -62,6 +62,7 @@ parsers.forEach(function (Parser) {
         assert.equal(el.getText(), 'Möwe')
       },
       'iso8859-1 text': function () {
+        if (Parser.name === 'SaxLibxmljs') return
         var el = parse('<?xml version="1.0" encoding="iso-8859-1"?><text>M\xF6we</text>')
         assert.equal(el.name, 'text')
         assert.equal(el.getText(), 'Möwe')
@@ -131,6 +132,8 @@ parsers.forEach(function (Parser) {
         })
         parser.write('<')
         parser.write('stream:features')
+        // otherwise libxmljs complains stream is not a defined NS
+        parser.write(' xmlns:stream="http://etherx.jabber.org/streams"')
         parser.write('>')
         parser.write('<')
         parser.write('mechanisms')
@@ -143,7 +146,9 @@ parsers.forEach(function (Parser) {
         assert.equal(events.length, 2)
         testStanza(events[0], {
           name: 'stream:features',
-          attrs: {}
+          attrs: {
+            'xmlns:stream': 'http://etherx.jabber.org/streams'
+          }
         })
         testStanza(events[1], {
           name: 'mechanisms',

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/ltx.git



More information about the Pkg-javascript-commits mailing list