diff --git a/src/parser/xmlHandler.js b/src/parser/xmlHandler.js index 28c7895b..8dc01f45 100644 --- a/src/parser/xmlHandler.js +++ b/src/parser/xmlHandler.js @@ -21,6 +21,18 @@ var NamespaceContext = require('./nscontext'); class XMLHandler { + /** + * @param {Object} [schemas] + * @param {Object} [options] + * @param {boolean} [options.enforceRestrictions] + * @param {string} [options.valueKey] + * @param {string} [options.xmlKey] + * @param {string} [options.attributesKey] + * @param {string} [options.xsiTypeKey] + * @param {Object} [options.date] + * @param {Object} [options.date.timezone] + * @param {boolean} [options.date.timezone.enabled] + */ constructor(schemas, options) { this.schemas = schemas || {}; this.options = options || {}; @@ -28,6 +40,9 @@ class XMLHandler { this.options.xmlKey = this.options.xmlKey || '$xml'; this.options.attributesKey = this.options.attributesKey || '$attributes'; this.options.xsiTypeKey = this.options.xsiTypeKey || '$xsiType'; + this.options.date = this.options.date || {}; + this.options.date.timezone = this.options.date.timezone || {}; + this.options.date.timezone.enabled = typeof this.options.date.timezone.enabled === 'boolean' ? this.options.date.timezone.enabled : true; } jsonToXml(node, nsContext, descriptor, val) { @@ -42,7 +57,7 @@ class XMLHandler { var name; let nameSpaceContextCreated = false; if (descriptor instanceof AttributeDescriptor) { - val = toXmlDateOrTime(descriptor, val); + val = toXmlDateOrTime(descriptor, val, this.options.date); name = descriptor.qname.name; if (descriptor.form === 'unqualified') { node.attribute(name, val); @@ -116,7 +131,7 @@ class XMLHandler { && typeof val[this.options.xmlKey] !== "undefined") { val = val[this.options.xmlKey]; element = node.element(elementName); - val = toXmlDateOrTime(descriptor, val); + val = toXmlDateOrTime(descriptor, val, this.options.date); element.raw(val); } else { // Enforce the type restrictions if configured for such @@ -137,7 +152,7 @@ class XMLHandler { } } } - val = toXmlDateOrTime(descriptor, val); + val = toXmlDateOrTime(descriptor, val, this.options.date); element = isSimple ? node.element(elementName, val) : node.element(elementName); } @@ -195,7 +210,7 @@ class XMLHandler { //val is not an object - simple or date types if (val != null && ( typeof val !== 'object' || val instanceof Date)) { // for adding a field value nsContext.popContext() shouldnt be called - val = toXmlDateOrTime(descriptor, val); + val = toXmlDateOrTime(descriptor, val, this.options.date); element.text(val); //add $attributes. Attribute can be an attribute defined in XSD or an xsi:type. //e.g of xsi:type some name @@ -288,7 +303,7 @@ class XMLHandler { mapObject(node, nsContext, descriptor, val, attrs) { if (val == null) return node; if (typeof val !== 'object' || (val instanceof Date)) { - val = toXmlDateOrTime(descriptor, val); + val = toXmlDateOrTime(descriptor, val, this.options.date); node.text(val); return node; } @@ -868,32 +883,50 @@ function parseValue(text, descriptor) { return value; } -function toXmlDate(date) { - date = new Date(date); - var isoStr = date.toISOString(); - return isoStr.split('T')[0] + 'Z'; +/** + * + * @param {string | Date} date + * @param {Object} [options] + * @param {Object} [options.timezone] + * @param {boolean} [options.timezone.enabled] + * @returns + */ +function toXmlDate(date, options) { + const isoStr = new Date(date).toISOString(); + const formattedDate = isoStr.split('T')[0]; + const withTimezone = (options && options.timezone) && typeof options.timezone.enabled === 'boolean' ? options.timezone.enabled : true; + if (!withTimezone) { + return formattedDate; + } + return formattedDate + 'Z'; } function toXmlTime(date) { - date = new Date(date); - var isoStr = date.toISOString(); + const isoStr = new Date(date).toISOString(); return isoStr.split('T')[1]; } function toXmlDateTime(date) { - date = new Date(date); - var isoStr = date.toISOString(); - return isoStr; + return new Date(date).toISOString(); } -function toXmlDateOrTime(descriptor, val) { +/** + * + * @param {object} descriptor + * @param {* | null} val + * @param {Object} options + * @param {Object} options.timezone + * @param {boolean} options.timezone.enabled + * @returns {string} + */ +function toXmlDateOrTime(descriptor, val, options) { if (!descriptor || !descriptor.type || val === null) return val; if (descriptor.type.name === 'date') { - val = toXmlDate(val); + return toXmlDate(val, options); } else if (descriptor.type.name === 'time') { - val = toXmlTime(val); + return toXmlTime(val); } else if (descriptor.type.name === 'dateTime') { - val = toXmlDateTime(val); + return toXmlDateTime(val); } return val; } diff --git a/test/xs-date-format-test.js b/test/xs-date-format-test.js index 437456ea..3e545a13 100644 --- a/test/xs-date-format-test.js +++ b/test/xs-date-format-test.js @@ -55,6 +55,15 @@ describe('xs-date-format-tests', function() { assert.equal(xmlDate, '2019-03-27Z'); }); + it('converts date to xml date without Z', function() { + var xmlDate = xmlHandler.toXmlDate(inputDate, { + timezone: { + enabled: false, + }, + }); + assert.equal(xmlDate, '2019-03-27'); + }); + it('converts date to xml time', function () { var xmlTime = xmlHandler.toXmlTime(inputDate); assert.equal(xmlTime, '04:01:01.000Z'); @@ -70,6 +79,16 @@ describe('xs-date-format-tests', function() { assert.equal(xmlDate, '2019-03-27Z'); }); + it('converts string to xml date without Z', function() { + var xmlDate = xmlHandler.toXmlDate(inputDateStr, { + timezone: { + enabled: false, + }, + }); + assert.equal(xmlDate, '2019-03-27'); + }); + + it('converts string to xml time', function () { var xmlTime = xmlHandler.toXmlTime(inputDateStr); assert.equal(xmlTime, '04:01:01.000Z');