moddle-xml
Advanced tools
Comparing version 0.6.0 to 0.7.0
@@ -11,4 +11,7 @@ 'use strict'; | ||
SaxParser = require('sax').parser, | ||
Moddle = require('moddle'), | ||
parseNameNs = require('moddle/lib/ns').parseName, | ||
Types = require('moddle/lib/types'), | ||
parseNameNs = require('moddle/lib/ns').parseName, | ||
coerceType = Types.coerceType, | ||
isSimpleType = Types.isSimple, | ||
common = require('./common'), | ||
@@ -100,11 +103,22 @@ XSI_TYPE = common.XSI_TYPE, | ||
* | ||
* @param {ElementHandler} parseRoot the root handler for parsing a document | ||
* @param {Object} options | ||
* @param {ElementHandler} options.parseRoot the root handler for parsing a document | ||
* @param {boolean} [options.lax=false] whether or not to ignore invalid elements | ||
*/ | ||
function Context(parseRoot) { | ||
function Context(options) { | ||
var elementsById = {}; | ||
var references = []; | ||
/** | ||
* @property {ElementHandler} parseRoot | ||
*/ | ||
var warnings = []; | ||
/** | ||
* @property {Boolean} lax | ||
*/ | ||
assign(this, options); | ||
var elementsById = this.elementsById = {}; | ||
var references = this.references = []; | ||
var warnings = this.warnings = []; | ||
this.addReference = function(reference) { | ||
@@ -126,12 +140,4 @@ references.push(reference); | ||
}; | ||
this.warnings = warnings; | ||
this.references = references; | ||
this.elementsById = elementsById; | ||
this.parseRoot = parseRoot; | ||
} | ||
function BaseHandler() {} | ||
@@ -143,2 +149,18 @@ | ||
/** | ||
* A simple pass through handler that does nothing except for | ||
* ignoring all input it receives. | ||
* | ||
* This is used to ignore unknown elements and | ||
* attributes. | ||
*/ | ||
function NoopHandler() { } | ||
NoopHandler.prototype = new BaseHandler(); | ||
NoopHandler.prototype.handleNode = function() { | ||
return this; | ||
}; | ||
function BodyHandler() {} | ||
@@ -194,3 +216,3 @@ | ||
value = Types.coerceType(propertyDesc.type, value); | ||
value = coerceType(propertyDesc.type, value); | ||
@@ -252,3 +274,3 @@ if (propertyDesc.isMany) { | ||
if (bodyProperty && value !== undefined) { | ||
value = Types.coerceType(bodyProperty.type, value); | ||
value = coerceType(bodyProperty.type, value); | ||
element.set(bodyProperty.name, value); | ||
@@ -282,3 +304,3 @@ } | ||
if (prop) { | ||
value = Types.coerceType(prop.type, value); | ||
value = coerceType(prop.type, value); | ||
} | ||
@@ -393,3 +415,3 @@ | ||
if (Types.isSimple(type)) { | ||
if (isSimpleType(type)) { | ||
return this.valueHandler(propertyDesc, element); | ||
@@ -481,6 +503,15 @@ } | ||
* | ||
* @param {Model} model used to read xml files | ||
* @param {Object} options | ||
* @param {Model} options.model used to read xml files | ||
* @param {Boolean} options.lax whether to make parse errors warnings | ||
*/ | ||
function XMLReader(model) { | ||
this.model = model; | ||
function XMLReader(options) { | ||
if (options instanceof Moddle) { | ||
options = { | ||
model: options | ||
}; | ||
} | ||
assign(this, { lax: false }, options); | ||
} | ||
@@ -491,3 +522,7 @@ | ||
var context = new Context(rootHandler); | ||
var model = this.model, | ||
lax = this.lax, | ||
context = new Context({ | ||
parseRoot: rootHandler | ||
}); | ||
@@ -497,4 +532,2 @@ var parser = new SaxParser(true, { xmlns: true, trim: true }), | ||
var model = this.model; | ||
rootHandler.context = context; | ||
@@ -560,10 +593,24 @@ | ||
console.error('failed to parse document'); | ||
console.error(e); | ||
throw new Error( | ||
var message = | ||
'unparsable content <' + node.name + '> detected\n\t' + | ||
'line: ' + line + '\n\t' + | ||
'column: ' + column + '\n\t' + | ||
'nested error: ' + e.message); | ||
'nested error: ' + e.message; | ||
if (lax) { | ||
context.addWarning({ | ||
message: message, | ||
error: e | ||
}); | ||
console.warn('could not parse node'); | ||
console.warn(e); | ||
stack.push(new NoopHandler()); | ||
} else { | ||
console.error('could not parse document'); | ||
console.error(e); | ||
throw new Error(message); | ||
} | ||
} | ||
@@ -570,0 +617,0 @@ } |
{ | ||
"name": "moddle-xml", | ||
"version": "0.6.0", | ||
"version": "0.7.0", | ||
"description": "XML import/export for documents described with moddle", | ||
@@ -5,0 +5,0 @@ "directories": { |
@@ -13,8 +13,7 @@ 'use strict'; | ||
var model = createModel(['properties']); | ||
var extendedModel = createModel(['properties', 'properties-extended']); | ||
describe('api', function() { | ||
var model = createModel([ 'properties' ]); | ||
it('should provide result with context', function(done) { | ||
@@ -66,2 +65,5 @@ | ||
var model = createModel([ 'properties' ]); | ||
var extendedModel = createModel([ 'properties', 'properties-extended' ]); | ||
describe('data types', function() { | ||
@@ -656,2 +658,4 @@ | ||
var extendedModel = createModel([ 'properties', 'properties-extended' ]); | ||
describe('should identify references', function() { | ||
@@ -734,2 +738,5 @@ | ||
var model = createModel([ 'properties' ]); | ||
var extendedModel = createModel([ 'properties', 'properties-extended' ]); | ||
it('should handle non-xml text files', function(done) { | ||
@@ -974,2 +981,116 @@ | ||
describe('lax error handling', function() { | ||
var model = createModel([ 'properties' ]); | ||
it('should ignore namespaced invalid child', function(done) { | ||
// given | ||
var reader = new Reader({ model: model, lax: true }); | ||
var rootHandler = reader.handler('props:ComplexAttrs'); | ||
var xml = '<props:complexAttrs xmlns:props="http://properties">' + | ||
'<props:unknownElement foo="bar">' + | ||
'<props:unknownChild />' + | ||
'</props:unknownElement>' + | ||
'</props:complexAttrs>'; | ||
reader.fromXML(xml, rootHandler, function(err, result, context) { | ||
if (err) { | ||
return done(err); | ||
} | ||
// then | ||
expect(context.warnings.length).to.eql(1); | ||
var warning = context.warnings[0]; | ||
expect(warning.message).to.eql( | ||
'unparsable content <props:unknownElement> detected\n\t' + | ||
'line: 0\n\t' + | ||
'column: 84\n\t' + | ||
'nested error: unknown type <props:UnknownElement>'); | ||
// then | ||
expect(result).to.jsonEqual({ | ||
$type: 'props:ComplexAttrs' | ||
}); | ||
done(); | ||
}); | ||
}); | ||
it('should ignore invalid child', function(done) { | ||
// given | ||
var reader = new Reader({ model: model, lax: true }); | ||
var rootHandler = reader.handler('props:ComplexAttrs'); | ||
var xml = '<props:complexAttrs xmlns:props="http://properties">' + | ||
'<unknownElement foo="bar" />' + | ||
'</props:complexAttrs>'; | ||
reader.fromXML(xml, rootHandler, function(err, result, context) { | ||
if (err) { | ||
return done(err); | ||
} | ||
// then | ||
expect(context.warnings.length).to.eql(1); | ||
var warning = context.warnings[0]; | ||
expect(warning.message).to.eql( | ||
'unparsable content <unknownElement> detected\n\t' + | ||
'line: 0\n\t' + | ||
'column: 80\n\t' + | ||
'nested error: unrecognized element <unknownElement>'); | ||
// then | ||
expect(result).to.jsonEqual({ | ||
$type: 'props:ComplexAttrs' | ||
}); | ||
done(); | ||
}); | ||
}); | ||
it('should ignore invalid attribute', function(done) { | ||
// given | ||
var reader = new Reader({ model: model, lax: true }); | ||
var rootHandler = reader.handler('props:ComplexAttrs'); | ||
var xml = '<props:complexAttrs xmlns:props="http://properties" unknownAttribute="FOO" />'; | ||
reader.fromXML(xml, rootHandler, function(err, result, context) { | ||
if (err) { | ||
return done(err); | ||
} | ||
expect(context.warnings).to.eql([]); | ||
// then | ||
expect(result).to.jsonEqual({ | ||
$type: 'props:ComplexAttrs' | ||
}); | ||
expect(result.$attrs).to.jsonEqual({ | ||
'xmlns:props': 'http://properties', | ||
unknownAttribute: 'FOO' | ||
}); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe('extension handling', function() { | ||
@@ -1244,2 +1365,3 @@ | ||
var model = createModel([ 'properties' ]); | ||
var extendedModel = createModel([ 'properties', 'properties-extended' ]); | ||
var extensionModel = createModel([ 'extensions' ]); | ||
@@ -1246,0 +1368,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
112883
3224