Skip to content

Adds support for <xs:choice minOccurs="0" maxOccurs="unbounded"/> cases.#1496

Open
4name wants to merge 1 commit into
vpulim:masterfrom
siriusxm:feature-choice-min-mac-occurs
Open

Adds support for <xs:choice minOccurs="0" maxOccurs="unbounded"/> cases.#1496
4name wants to merge 1 commit into
vpulim:masterfrom
siriusxm:feature-choice-min-mac-occurs

Conversation

@4name

@4name 4name commented Jun 4, 2026

Copy link
Copy Markdown

That PR fixes <xsd:choice minOccurs="0" maxOccurs="unbounded"/> behavior. Before that, the WSDL marshaller could resolve this only as two (or more) separate type lists. The following JSON object has two separate lists of As and Bs:

Assuming we have the following definitions of some Document:

<>
    <!-- Parent document WSDL definition -->
    <xsd:element name="someOtherProperty" type="ct:SomeOtherType"/>
    <xsd:choice minOccurs="0" maxOccurs="unbounded">
        <xsd:element name="a" type="ct:A"/>
        <xsd:element name="b" type="ct:B"/>
    </xsd:choice>
</>

// Old behavior

{
    // Parent document JSON representation
    someOtherProperty: { ... SomeOtherType-type object ... },
    a: [ { ... A-type object 1 ... }, { ... A-type object 2 ... }, ...],
    b: [ { ... B-type object 1 ... }, { ... B-type object 2 ... }, { ... B-type object 3 ... }, ...],
}

that resulted into:

<>
    <!-- Parent document XML representation -->
    <someOtherProperty> ... SomeOtherType properties ... </someOtherProperty>
    <a> ... A-type properties 1 ... </a>
    <a> ... A-type properties 2 ... </a>
    <b> ... B-type properties 1 ... </b>
    <b> ... B-type properties 2 ... </b>
    <b> ... B-type properties 3 ... </b>
</>

In case we want to preserve the choice children order for the following JSON object:

// New behavior

{
    // Parent document JSON representation
    someOtherProperty: { ... SomeOtherType-type object ... },
    '$sequence': [ // <- Note this special transparent key that wraps a flat array object
        a: { ... A-type object 1 ... },
        b: { ... B-type object 1 ... },
        b: { ... B-type object 2 ... },
        a: { ... A-type object 2 ... },
        b: { ... B-type object 3 ... },
    ]
}

to be encoded as:

<>
    <!-- Parent document XML representation -->
    <someOtherProperty> ... SomeOtherType properties ... </someOtherProperty>
    <a> ... A-type properties 1 ... </a> <!-- Note that As and Bs tags are on the same level with someOtherProperty -->
    <b> ... B-type properties 1 ... </b>
    <b> ... B-type properties 2 ... </b>
    <a> ... A-type properties 2 ... </a> <!-- Note that we can mix As and Bs order now -->
    <b> ... B-type properties 3 ... </b>
</>

In case of interfere with $sequence property of some SOAP Service property, the special key name can be replaced with options arrayWithChoiceTag: string value.

Summary by CodeRabbit

Release Notes

  • New Features
    • Added arrayWithChoiceTag configuration option for customizing XML serialization of polymorphic array elements in SOAP operations.

That PR fixes <xsd:choice minOccurs="0" maxOccurs="unbounded"/> behavior. Before that, the WSDL marshaller could resolve this only as two (or more) separate type lists. The following JSON object has two separate lists of As and Bs:

Assuming we have the following definitions of some Document:
<>
    <!-- Parent document WSDL definition -->
    <xsd:element name="someOtherProperty" type="ct:SomeOtherType"/>
    <xsd:choice minOccurs="0" maxOccurs="unbounded">
        <xsd:element name="a" type="ct:A"/>
        <xsd:element name="b" type="ct:B"/>
    </xsd:choice>
</>

// Old behavior
{
    // Parent document JSON representation
    someOtherProperty: { ... SomeOtherType-type object ... },
    a: [ { ... A-type object 1 ... }, { ... A-type object 2 ... }, ...],
    b: [ { ... B-type object 1 ... }, { ... B-type object 2 ... }, { ... B-type object 3 ... }, ...],
}

that resulted into:
<>
    <!-- Parent document XML representation -->
    <someOtherProperty> ... SomeOtherType properties ... </someOtherProperty>
    <a> ... A-type properties 1 ... </a>
    <a> ... A-type properties 2 ... </a>
    <b> ... B-type properties 1 ... </b>
    <b> ... B-type properties 2 ... </b>
    <b> ... B-type properties 3 ... </b>
</>

In case we want to preserve the choice children order for the following JSON object:

// New behavior
{
    // Parent document JSON representation
    someOtherProperty: { ... SomeOtherType-type object ... },
    '$sequence': [ // <- Note this special transparent key that wraps a flat array object
        a: { ... A-type object 1 ... },
        b: { ... B-type object 1 ... },
        b: { ... B-type object 2 ... },
        a: { ... A-type object 2 ... },
        b: { ... B-type object 3 ... },
    ]
}

to be encoded as:
<>
    <!-- Parent document XML representation -->
    <someOtherProperty> ... SomeOtherType properties ... </someOtherProperty>
    <a> ... A-type properties 1 ... </a> <!-- Note that As and Bs tags are on the same level with someOtherProperty -->
    <b> ... B-type properties 1 ... </b>
    <b> ... B-type properties 2 ... </b>
    <a> ... A-type properties 2 ... </a> <!-- Note that we can mix As and Bs order now -->
    <b> ... B-type properties 3 ... </b>
</>

In case of interfere with $sequence property of some SOAP Service property, the special key name can be replaced with options arrayWithChoiceTag: string value.
@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds support for custom array choice tag configuration during SOAP XML marshaling. A new optional arrayWithChoiceTag option is introduced, the serialization logic detects and handles matching arrays by skipping wrapper tags, and comprehensive tests validate both custom and default behaviors.

Changes

Array Choice Tag Customization

Layer / File(s) Summary
Configuration option and initialization
src/types.ts, src/wsdl/index.ts
Adds arrayWithChoiceTag?: string property to IWsdlBaseOptions with documented semantics, initialized to '$sequence' by default during WSDL options setup.
Array choice container serialization
src/wsdl/index.ts
Modifies objectToXML array loop to bypass opening/closing tags and attributes when array name matches arrayWithChoiceTag, emitting only the computed body; conditionally passes schema object only for matching elements during recursion.
Test WSDL contract for mixed-sequence
test/wsdl/complex/mixed-sequence.wsdl
Defines complete WSDL specification with XML Schema types, request/response elements, abstract and concrete data types, port type operations with fault bindings, and SOAP service endpoint.
Validation tests for array choice serialization
test/wsdl-parse-test.js
Two test cases validate XML serialization behavior: one with custom arrayWithChoiceTag: '$arrayChoice' and one with default $sequence, each asserting exact XML output from parsed and converted payloads.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A choice of arrays wrapped with customizable care,
No more rigid $sequence tags everywhere!
With arrayWithChoiceTag, the WSDL takes flight,
XML marshaling now fits just right. ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main feature being added: support for xs:choice elements with minOccurs and maxOccurs attributes in unbounded arrays.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/wsdl-parse-test.js`:
- Around line 159-161: The test is using def.findSchemaType to look up the
element "getDataResponse" but that element has an anonymous complex type, so
change both lookups to use def.findSchemaObject('getDataResponse',
'http://test-soap.com/api/mixedsequence') instead of def.findSchemaType; update
the two occurrences around the current getDataResponse assertions (the call at
the earlier block and the similar call at the later block around lines 231-233)
so the test queries the schema object (element) rather than searching for a
named type.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 88fff7ac-e81b-419d-856b-704aa6b2b01f

📥 Commits

Reviewing files that changed from the base of the PR and between 2869f51 and 751ca0a.

📒 Files selected for processing (4)
  • src/types.ts
  • src/wsdl/index.ts
  • test/wsdl-parse-test.js
  • test/wsdl/complex/mixed-sequence.wsdl

Comment thread test/wsdl-parse-test.js
Comment on lines +159 to +161
if (null === def.findSchemaType('getDataResponse', 'http://test-soap.com/api/mixedsequence')) {
return done('Unable to find "getDataResponse" complex type');
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use findSchemaObject for getDataResponse lookup.

Line 159 and Line 231 call findSchemaType, but getDataResponse is an element with an anonymous complex type in mixed-sequence.wsdl, so this lookup is incorrect.

💡 Proposed fix
-        if (null === def.findSchemaType('getDataResponse', 'http://test-soap.com/api/mixedsequence')) {
-          return done('Unable to find "getDataResponse" complex type');
+        if (null === def.findSchemaObject('http://test-soap.com/api/mixedsequence', 'getDataResponse')) {
+          return done('Unable to find "getDataResponse" schema object');
         }
@@
-        if (null === def.findSchemaType('getDataResponse', 'http://test-soap.com/api/mixedsequence')) {
-          return done('Unable to find "getDataResponse" complex type');
+        if (null === def.findSchemaObject('http://test-soap.com/api/mixedsequence', 'getDataResponse')) {
+          return done('Unable to find "getDataResponse" schema object');
         }

Also applies to: 231-233

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/wsdl-parse-test.js` around lines 159 - 161, The test is using
def.findSchemaType to look up the element "getDataResponse" but that element has
an anonymous complex type, so change both lookups to use
def.findSchemaObject('getDataResponse',
'http://test-soap.com/api/mixedsequence') instead of def.findSchemaType; update
the two occurrences around the current getDataResponse assertions (the call at
the earlier block and the similar call at the later block around lines 231-233)
so the test queries the schema object (element) rather than searching for a
named type.

@w666

w666 commented Jun 7, 2026

Copy link
Copy Markdown
Collaborator

Hi @4name. thanks for the PR. I am a bit overcomited atm, but this PR is on my backlog. I will have a look as soon as I can, Thanks.

Also, need to silent that CodeRabbit, too much noise from it.

@4name

4name commented Jun 8, 2026

Copy link
Copy Markdown
Author

Hi @w666! Thank you for the notice, take your time. Please let me know if there is anything that needs to be improved in that PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants