diff --git a/CHANGES.md b/CHANGES.md index 89ef8b2c..e83f00a7 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,10 @@ +2024-11-11, Version 4.1.6 +========================= + +Placeholder for package maintainer + + * feat: Override default strong-soap behaviour when mapping undefined element values to self closing tags ( instead of . Option is ignoreAttributesUndefined, to enable option set to false. (Jamie Nicholson) + 2024-10-10, Version 4.1.5 ========================= diff --git a/README.md b/README.md index 57408d64..54e84b2b 100644 --- a/README.md +++ b/README.md @@ -530,6 +530,10 @@ soap.createClient(__dirname + '/wsdl/default_namespace.wsdl', wsdlOptions, funct To see it in practice, consider the sample in: [test/request-response-samples/addPets__force_namespaces](https://github.com/loopbackio/strong-soap/tree/master/test/request-response-samples/addPets__force_namespaces) +### Mapping of undefined element values + +When the wsdl attribute nillable="true" it set, JSON values will map to null and XML values map to nillable='true' unless ignoreAttributesUndefined is set to false. When ignoreAttributesUndefined is set to false undefined element values will map to a self closing tag i.e. + ## XMLHandler XMLHandler enables you to to convert a JSON object to XML and XML to a JSON object. It can also parse an XML string or stream into the XMLBuilder tree. diff --git a/src/parser/xmlHandler.js b/src/parser/xmlHandler.js index 2a2e7044..0538316f 100644 --- a/src/parser/xmlHandler.js +++ b/src/parser/xmlHandler.js @@ -32,6 +32,7 @@ class XMLHandler { * @param {Object} [options.date] * @param {Object} [options.date.timezone] * @param {boolean} [options.date.timezone.enabled] + * @param {boolean} [option.ignoreAttributesUndefined] */ constructor(schemas, options) { this.schemas = schemas || {}; @@ -43,6 +44,7 @@ class XMLHandler { 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; + this.options.ignoreAttributesUndefined = typeof this.options.ignoreAttributesUndefined === 'boolean' ? this.options.ignoreAttributesUndefined : true; } jsonToXml(node, nsContext, descriptor, val) { @@ -162,8 +164,8 @@ class XMLHandler { } } - if (val == null) { - if (descriptor.isNillable) { + if (val === null ||(val === undefined && this.options.ignoreAttributesUndefined == true)) { + if (descriptor.isNillable ) { // Set xsi:nil = true declareNamespace(nsContext, element, 'xsi', helper.namespaces.xsi); if (typeof element.attribute === 'function') { diff --git a/test/undefined-test.js b/test/undefined-test.js new file mode 100644 index 00000000..1b9f9df4 --- /dev/null +++ b/test/undefined-test.js @@ -0,0 +1,99 @@ +// Copyright IBM Corp. 2017. All Rights Reserved. +// Node module: strong-soap +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +"use strict"; + +var soap = require('..').soap, + assert = require('assert'); + +describe('Undefined tests', function() { + + /* + If value of 'breed' (simpleType in the WSDL) is undefined, + and options.ignoreAttributesUndefined is true, the element will be empty. + + Request + + + + + + + max + + + + sunny + Labrador + + + + + */ + + it("undefined and options.ignoreAttributesUndefined false for simpleType", function (done) { + soap.createClient(__dirname + '/wsdl/strict/nillable.wsdl',{ + "ignoreAttributesUndefined":false + }, function (err, client) { + assert.ok(!err); + var requestArgs = { + "pet": [ + { + "Name" : "max", + "Breed" : undefined + }, + { + "Name": "sunny", + "Breed": "Labrador" + } + ] + }; + + client.addPets(requestArgs, function (err, result, body) { + var request = client.lastMessage; + //check if the Breed element is empty + var index = request.indexOf(''); + assert.ok(index > -1); + done(); + }); + }); + }); + + /* + In case of nillable="true" defined on 'pet' complexType in the WSDL. If value of 'pet' is undefined, + and options.ignoreAttributesUndefined is true the element will be empty. + + Request + + + + + + + + + + */ + + it("undefined and options.ignoreAttributesUndefined false for complexType", function (done) { + soap.createClient(__dirname + '/wsdl/strict/nillable.wsdl',{ + "ignoreAttributesUndefined":false + }, function (err, client) { + assert.ok(!err); + var requestArgs = { + "pet": undefined + }; + + client.addPets(requestArgs, function (err, result, body) { + var request = client.lastMessage; + //check if the pet element has xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" atttribute + var index = request.indexOf(''); + assert.ok(index > -1); + done(); + }); + }); + }); + +}); \ No newline at end of file