diff --git a/src/wsdl/elements.ts b/src/wsdl/elements.ts index a05042ae..6e668d94 100644 --- a/src/wsdl/elements.ts +++ b/src/wsdl/elements.ts @@ -383,18 +383,32 @@ export class RestrictionElement extends Element { 'choice', 'enumeration', 'sequence', + 'attribute', ]); public $base: string; public description(definitions?: DefinitionsElement, xmlns?: IXmlNs) { const children = this.children; let desc; - for (let i = 0, child; child = children[i]; i++) { - if (child instanceof SequenceElement || child instanceof ChoiceElement) { + let isFirstChild = false; + const $attributes = {}; + + for (const child of children) { + if (child instanceof AttributeElement) { + $attributes[child.$name] = child.description(definitions); + continue; + } + if (!isFirstChild && (child instanceof SequenceElement || child instanceof ChoiceElement)) { + isFirstChild = true; desc = child.description(definitions, xmlns); - break; } } + + if (Object.keys($attributes).length > 0) { + desc = desc ?? {}; + desc[AttributeElement.Symbol] = $attributes; + } + if (desc && this.$base) { const type = splitQName(this.$base); const typeName = type.name; @@ -405,11 +419,16 @@ export class RestrictionElement extends Element { desc.getBase = () => { return typeElement.description(definitions, schema.xmlns); }; + if (typeElement) { + const baseDescription = typeElement.description(definitions, schema.xmlns); + if (baseDescription[AttributeElement.Symbol]) { + _.defaults($attributes, baseDescription[AttributeElement.Symbol]); + } + desc = _.defaults(desc, baseDescription); + } return desc; } - // then simple element - const base = this.$base ? this.$base + '|' : ''; const restrictions = this.children.map((child) => { return child.description(); }).join(','); @@ -525,10 +544,12 @@ export class ComplexTypeElement extends Element { export class ComplexContentElement extends Element { public readonly allowedChildren = buildAllowedChildren([ 'extension', + 'restriction', ]); + public description(definitions: DefinitionsElement, xmlns: IXmlNs) { for (const child of this.children) { - if (child instanceof ExtensionElement) { + if (child instanceof ExtensionElement || child instanceof RestrictionElement) { return child.description(definitions, xmlns); } } diff --git a/test/wsdl-test.js b/test/wsdl-test.js index 896a6a6f..3b21bbe3 100644 --- a/test/wsdl-test.js +++ b/test/wsdl-test.js @@ -370,4 +370,19 @@ describe('WSDL Parser (non-strict)', () => { done(); }); }); + + it('Should describe return correct result for attributes in complexTypeElement with restrictions', function(done) { + soap.createClient(__dirname+ '/wsdl/wsdl_with_restriction_attributes.wsdl', function(err,client){ + assert.ifError(err); + var description = client.describe(); + assert.deepStrictEqual(description.SampleService.SamplePort.GetPerson.output.ObjectDetails[elements.AttributeElement.Symbol], { + id: { type: 'xsd:string', required: true }, + type: { type: 'xsd:long', required: true }, + internalName: { type: 'xsd:string', required: false }, + key: { type: 'xsd:string', required: false }, + origin: { type: 'xsd:string', required: false } + }); + done(); + }); + }); }); diff --git a/test/wsdl/wsdl_with_restriction_attributes.wsdl b/test/wsdl/wsdl_with_restriction_attributes.wsdl new file mode 100644 index 00000000..134cdb8e --- /dev/null +++ b/test/wsdl/wsdl_with_restriction_attributes.wsdl @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +