diff --git a/src/types.ts b/src/types.ts
index 896a0bf08..80396ab8b 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -99,6 +99,8 @@ export interface IWsdlBaseOptions {
preserveWhitespace?: boolean;
/** provides support for nonstandard array semantics. If true, JSON arrays of the form {list: [{elem: 1}, {elem: 2}]} are marshalled into xml as 1
2
. If false, marshalls into 1 2
. Default: true. */
namespaceArrayElements?: boolean;
+ /** provides support for array with choice semantics. If array key matches, JSON arrays of the form {$sequence: [{elem: 1}, {elem: 2}]} are marshalled into xml as 12. Default: $sequence. */
+ arrayWithChoiceTag?: string;
useEmptyTag?: boolean;
strict?: boolean;
/** custom HTTP headers to be sent on WSDL requests. */
diff --git a/src/wsdl/index.ts b/src/wsdl/index.ts
index 68fc61705..f80ee00a2 100644
--- a/src/wsdl/index.ts
+++ b/src/wsdl/index.ts
@@ -750,31 +750,36 @@ export class WSDL {
for (i = 0, n = obj.length; i < n; i++) {
const item = obj[i];
- const arrayAttr = this.processAttributes(item, nsContext);
+ const isArrayWithChoiceTagContainer = name === this.options.arrayWithChoiceTag;
+ const arrayAttr = isArrayWithChoiceTagContainer ? '' : this.processAttributes(item, nsContext);
const correctOuterNsPrefix = nonSubNameSpace || parentNsPrefix || ns; // using the parent namespace prefix if given
const body = this.objectToXML(item, name, nsPrefix, nsURI, false, null, schemaObject, nsContext);
- let openingTagParts = ['<', name, arrayAttr, xmlnsAttrib];
- if (!emptyNonSubNameSpaceForArray) {
- openingTagParts = ['<', appendColon(correctOuterNsPrefix), name, arrayAttr, xmlnsAttrib];
- }
-
- if (body === '' && this.options.useEmptyTag) {
- // Use empty (self-closing) tags if no contents
- openingTagParts.push(' />');
- parts.push(openingTagParts.join(''));
+ if (isArrayWithChoiceTagContainer) {
+ parts.push(body);
} else {
- openingTagParts.push('>');
- if (this.options.namespaceArrayElements || i === 0) {
- parts.push(openingTagParts.join(''));
+ let openingTagParts = ['<', name, arrayAttr, xmlnsAttrib];
+ if (!emptyNonSubNameSpaceForArray) {
+ openingTagParts = ['<', appendColon(correctOuterNsPrefix), name, arrayAttr, xmlnsAttrib];
}
- parts.push(body);
- if (this.options.namespaceArrayElements || i === n - 1) {
- if (emptyNonSubNameSpaceForArray) {
- parts.push(['', name, '>'].join(''));
- } else {
- parts.push(['', appendColon(correctOuterNsPrefix), name, '>'].join(''));
+
+ if (body === '' && this.options.useEmptyTag) {
+ // Use empty (self-closing) tags if no contents
+ openingTagParts.push(' />');
+ parts.push(openingTagParts.join(''));
+ } else {
+ openingTagParts.push('>');
+ if (this.options.namespaceArrayElements || i === 0) {
+ parts.push(openingTagParts.join(''));
+ }
+ parts.push(body);
+ if (this.options.namespaceArrayElements || i === n - 1) {
+ if (emptyNonSubNameSpaceForArray) {
+ parts.push(['', name, '>'].join(''));
+ } else {
+ parts.push(['', appendColon(correctOuterNsPrefix), name, '>'].join(''));
+ }
}
}
}
@@ -939,7 +944,7 @@ export class WSDL {
}
}
- value = this.objectToXML(child, name, nsPrefix, nsURI, false, null, null, nsContext);
+ value = this.objectToXML(child, name, nsPrefix, nsURI, false, null, name === this.options.arrayWithChoiceTag ? schemaObject : null, nsContext);
}
} else {
value = this.objectToXML(child, name, nsPrefix, nsURI, false, null, null, nsContext);
@@ -1178,6 +1183,7 @@ export class WSDL {
} else {
this.options.namespaceArrayElements = true;
}
+ this.options.arrayWithChoiceTag = options.arrayWithChoiceTag || '$sequence';
// Allow any request headers to keep passing through
this.options.wsdl_headers = options.wsdl_headers;
diff --git a/test/wsdl-parse-test.js b/test/wsdl-parse-test.js
index 87709f26f..d46fd0930 100644
--- a/test/wsdl-parse-test.js
+++ b/test/wsdl-parse-test.js
@@ -144,4 +144,151 @@ describe(__filename, function () {
done();
});
});
+
+ it('should parse complex wsdls with mixed choice and minOccurs maxOccurs with custom $sequence', function (done) {
+ open_wsdl(
+ path.resolve(__dirname, 'wsdl/complex/mixed-sequence.wsdl'),
+ {
+ arrayWithChoiceTag: '$arrayChoice',
+ },
+ function (err, def) {
+ if (err) {
+ return done(err);
+ }
+
+ if (null === def.findSchemaType('getDataResponse', 'http://test-soap.com/api/mixedsequence')) {
+ return done('Unable to find "getDataResponse" complex type');
+ }
+
+ var requestBody = {
+ getDataResult: {
+ a: 0,
+ b: 10,
+ $arrayChoice: [
+ {
+ c: {
+ id: '1',
+ value1: 'test 1',
+ },
+ },
+ {
+ d: {
+ id: '3',
+ value2: 'test 3',
+ },
+ },
+ {
+ c: {
+ id: '2',
+ value1: 'test 2',
+ },
+ },
+ ],
+ },
+ };
+
+ var requestAsXML = def.objectToDocumentXML('getDataResponse', requestBody, 'acme', 'http://test-soap.com/api/mixedsequence', 'getDataResponse');
+
+ /**
+ * Expected XML:
+ *
+ *
+ * 0
+ * 10
+ *
+ * 1
+ * test 1
+ *
+ *
+ * 3
+ * test 3
+ *
+ *
+ * 2
+ * test 2
+ *
+ *
+ *
+ */
+ assert.strictEqual(
+ requestAsXML,
+ '0101test 13test 32test 2',
+ );
+
+ done();
+ },
+ );
+ });
+
+ it('should parse complex wsdls with mixed choice and minOccurs maxOccurs with default $sequence', function (done) {
+ open_wsdl(
+ path.resolve(__dirname, 'wsdl/complex/mixed-sequence.wsdl'),
+ function (err, def) {
+ if (err) {
+ return done(err);
+ }
+
+ if (null === def.findSchemaType('getDataResponse', 'http://test-soap.com/api/mixedsequence')) {
+ return done('Unable to find "getDataResponse" complex type');
+ }
+
+ var requestBody = {
+ getDataResult: {
+ a: 0,
+ b: 10,
+ $sequence: [
+ {
+ c: {
+ id: '1',
+ value1: 'test 1',
+ },
+ },
+ {
+ d: {
+ id: '3',
+ value2: 'test 3',
+ },
+ },
+ {
+ c: {
+ id: '2',
+ value1: 'test 2',
+ },
+ },
+ ],
+ },
+ };
+
+ var requestAsXML = def.objectToDocumentXML('getDataResponse', requestBody, 'acme', 'http://test-soap.com/api/mixedsequence', 'getDataResponse');
+
+ /**
+ * Expected XML:
+ *
+ *
+ * 0
+ * 10
+ *
+ * 1
+ * test 1
+ *
+ *
+ * 3
+ * test 3
+ *
+ *
+ * 2
+ * test 2
+ *
+ *
+ *
+ */
+ assert.strictEqual(
+ requestAsXML,
+ '0101test 13test 32test 2',
+ );
+
+ done();
+ },
+ );
+ });
});
diff --git a/test/wsdl/complex/mixed-sequence.wsdl b/test/wsdl/complex/mixed-sequence.wsdl
new file mode 100644
index 000000000..bcae576d8
--- /dev/null
+++ b/test/wsdl/complex/mixed-sequence.wsdl
@@ -0,0 +1,127 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+