Skip to content

Commit

Permalink
Merge branch 'GH-172'
Browse files Browse the repository at this point in the history
  • Loading branch information
ncb000gt committed Jan 6, 2013
2 parents ceb6f23 + 4e72d02 commit 5bae57d
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 0 deletions.
18 changes: 18 additions & 0 deletions lib/document.js
Expand Up @@ -73,6 +73,24 @@ Document.prototype.validate = function(xsd) {
return this._validate(xsd);
};

Document.prototype.setDtd = function(name, ext, sys) {
if (!name) {
throw new Error('Must pass in a DTD name');
} else if (typeof name !== 'string') {
throw new Error('Must pass in a valid DTD name');
}

var params = [name];
if (typeof ext !== 'undefined') {
params.push(ext);
}
if (ext && typeof sys !== 'undefined') {
params.push(sys);
}

return this._setDtd.apply(this, params);
};

/// @return array of namespaces in document
Document.prototype.namespaces = function() {
return this.root().namespaces();
Expand Down
43 changes: 43 additions & 0 deletions src/xml_document.cc
Expand Up @@ -3,6 +3,8 @@
#include <node.h>
#include <node_buffer.h>

#include <cstring>

#include <libxml/HTMLparser.h>
#include <libxml/xmlschemas.h>

Expand Down Expand Up @@ -86,6 +88,43 @@ XmlDocument::Root(const v8::Arguments& args)
return scope.Close(args[0]);
}

v8::Handle<v8::Value>
XmlDocument::SetDtd(const v8::Arguments& args)
{
v8::HandleScope scope;

XmlDocument* document = ObjectWrap::Unwrap<XmlDocument>(args.Holder());
assert(document);

v8::String::Utf8Value name(args[0]);

v8::Handle<v8::Value> extIdOpt;
v8::Handle<v8::Value> sysIdOpt;
if (args.Length() > 1 && args[1]->IsString()) {
extIdOpt = args[1];
}
if (args.Length() > 2 && args[2]->IsString()) {
sysIdOpt = args[2];
}

v8::String::Utf8Value extIdRaw(extIdOpt);
v8::String::Utf8Value sysIdRaw(sysIdOpt);

//must be set to null in order for xmlCreateIntSubset to ignore them
const char* extId = (extIdRaw.length()) ? *extIdRaw : NULL;
const char* sysId = (sysIdRaw.length()) ? *sysIdRaw : NULL;

//No good way of unsetting the doctype if it is previously set...this allows us to.
xmlDtdPtr dtd = xmlGetIntSubset(document->xml_obj);

xmlUnlinkNode((xmlNodePtr) dtd);
xmlFreeNode((xmlNodePtr) dtd);

xmlCreateIntSubset(document->xml_obj, (const xmlChar *) *name, (const xmlChar *) extId, (const xmlChar *) sysId);

return scope.Close(args.Holder());
}

v8::Handle<v8::Value>
XmlDocument::ToString(const v8::Arguments& args)
{
Expand Down Expand Up @@ -332,6 +371,10 @@ XmlDocument::Initialize(v8::Handle<v8::Object> target)
NODE_SET_PROTOTYPE_METHOD(constructor_template,
"_validate",
XmlDocument::Validate);
NODE_SET_PROTOTYPE_METHOD(constructor_template,
"_setDtd",
XmlDocument::SetDtd);


NODE_SET_METHOD(target, "fromXml", XmlDocument::FromXml);
NODE_SET_METHOD(target, "fromHtml", XmlDocument::FromHtml);
Expand Down
1 change: 1 addition & 0 deletions src/xml_document.h
Expand Up @@ -42,6 +42,7 @@ class XmlDocument : public node::ObjectWrap {
static v8::Handle<v8::Value> New(const v8::Arguments& args);
static v8::Handle<v8::Value> FromHtml(const v8::Arguments& args);
static v8::Handle<v8::Value> FromXml(const v8::Arguments& args);
static v8::Handle<v8::Value> SetDtd(const v8::Arguments& args);

// document handle methods
static v8::Handle<v8::Value> Root(const v8::Arguments& args);
Expand Down
24 changes: 24 additions & 0 deletions test/document.js
@@ -1,5 +1,29 @@
var libxml = require('../index');

module.exports.setDtd = function(assert) {
var doc = libxml.Document();
doc.setDtd("html");
assert.ok(doc);
assert.equal('<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE html>\n', doc.toString());
doc.setDtd("html", "bacon", "bacon");
assert.ok(doc);
assert.equal('<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE html PUBLIC "bacon" "bacon">\n', doc.toString());
doc.setDtd("html", null);
assert.ok(doc);
assert.equal('<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE html>\n', doc.toString());
assert.throws(function() {
doc.setDtd(5);
});
assert.ok(doc);
assert.equal('<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE html>\n', doc.toString());
assert.throws(function() {
doc.setDtd();
});
assert.ok(doc);
assert.equal('<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE html>\n', doc.toString());
assert.done();
};

module.exports.blank = function(assert) {
var doc = libxml.Document();
assert.ok(doc);
Expand Down

0 comments on commit 5bae57d

Please sign in to comment.