Skip to content

Commit c09ea95

Browse files
authored
Use wsdl xmlns prefix mappings (#1279)
Close #1276
1 parent bb39035 commit c09ea95

File tree

5 files changed

+111
-12
lines changed

5 files changed

+111
-12
lines changed

src/wsdl/elements.ts

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ export class Element {
7070
public nsName?;
7171
public prefix?: string;
7272
public schemaXmlns?;
73+
public definitionsXmlns?: IXmlNs;
7374
public valueKey: string;
7475
public xmlKey;
7576
public xmlns?: IXmlNs;
@@ -132,6 +133,10 @@ export class Element {
132133
if (ChildClass) {
133134
const child = new ChildClass(nsName, attrs, options, schemaXmlns);
134135
child.init();
136+
const root = stack[0];
137+
if (root instanceof DefinitionsElement) {
138+
child.definitionsXmlns = root.xmlns;
139+
}
135140
stack.push(child);
136141
} else {
137142
this.unexpected(nsName);
@@ -240,10 +245,9 @@ export class ElementElement extends Element {
240245
if (type) {
241246
type = splitQName(type);
242247
const typeName: string = type.name;
243-
const ns: string = xmlns && xmlns[type.prefix] ||
244-
this.xmlns[type.prefix] ||
245-
((definitions.xmlns[type.prefix] !== undefined || definitions.xmlns[this.targetNSAlias] !== undefined) && this.schemaXmlns[type.prefix]) ||
246-
definitions.xmlns[type.prefix];
248+
const useSchemaXmlns = !!findNs(type.prefix, this.definitionsXmlns, definitions.xmlns) ||
249+
!!findNs(this.targetNSAlias, this.definitionsXmlns, definitions.xmlns);
250+
const ns = findNs(type.prefix, xmlns, this.xmlns, useSchemaXmlns ? this.schemaXmlns : undefined, this.definitionsXmlns, definitions.xmlns);
247251
const schema = definitions.schemas[ns];
248252
const typeElement = schema && (this.$type ? schema.complexTypes[typeName] || schema.types[typeName] : schema.elements[typeName]);
249253
const typeStorage = this.$type ? definitions.descriptions.types : definitions.descriptions.elements;
@@ -419,7 +423,7 @@ export class RestrictionElement extends Element {
419423
if (desc && this.$base) {
420424
const type = splitQName(this.$base);
421425
const typeName = type.name;
422-
const ns = xmlns && xmlns[type.prefix] || definitions.xmlns[type.prefix];
426+
const ns = findNs(type.prefix, xmlns, this.definitionsXmlns, definitions.xmlns);
423427
const schema = definitions.schemas[ns];
424428
const typeElement = schema && (schema.complexTypes[typeName] || schema.types[typeName] || schema.elements[typeName]);
425429

@@ -462,7 +466,7 @@ export class ExtensionElement extends Element {
462466
if (this.$base) {
463467
const type = splitQName(this.$base);
464468
const typeName = type.name;
465-
const ns = xmlns && xmlns[type.prefix] || definitions.xmlns[type.prefix];
469+
const ns = findNs(type.prefix, xmlns, this.definitionsXmlns, definitions.xmlns);
466470
const schema = definitions.schemas[ns];
467471

468472
if (typeName in Primitives) {
@@ -662,15 +666,15 @@ export class MessageElement extends Element {
662666
delete this.parts;
663667

664668
const nsName = splitQName(part.$element);
665-
const ns = nsName.prefix;
666-
let schema = definitions.schemas[definitions.xmlns[ns]];
669+
const ns = findNs(nsName.prefix, this.definitionsXmlns, definitions.xmlns);
670+
let schema = definitions.schemas[ns];
667671
this.element = schema.elements[nsName.name];
668672
if (!this.element) {
669673
debug(nsName.name + ' is not present in wsdl and cannot be processed correctly.');
670674
return;
671675
}
672-
this.element.targetNSAlias = ns;
673-
this.element.targetNamespace = definitions.xmlns[ns];
676+
this.element.targetNSAlias = nsName.prefix;
677+
this.element.targetNamespace = ns;
674678

675679
// set the optional $lookupType to be used within `client#_invoke()` when
676680
// calling `wsdl#objectToDocumentXML()
@@ -705,7 +709,7 @@ export class MessageElement extends Element {
705709

706710
if (this.element.$type) {
707711
const type = splitQName(this.element.$type);
708-
const typeNs = schema.xmlns && schema.xmlns[type.prefix] || definitions.xmlns[type.prefix];
712+
const typeNs = findNs(type.prefix, schema.xmlns, this.definitionsXmlns, definitions.xmlns);
709713

710714
if (typeNs) {
711715
if (type.name in Primitives) {
@@ -737,7 +741,7 @@ export class MessageElement extends Element {
737741
}
738742
assert(part.name === 'part', 'Expected part element');
739743
const nsName = splitQName(part.$type);
740-
const ns = definitions.xmlns[nsName.prefix];
744+
const ns = findNs(nsName.prefix, this.definitionsXmlns, definitions.xmlns);
741745
const type = nsName.name;
742746
const schemaDefinition = definitions.schemas[ns];
743747
if (typeof schemaDefinition !== 'undefined') {
@@ -1257,3 +1261,14 @@ function buildAllowedChildren(elementList: string[]): { [k: string]: typeof Elem
12571261
}
12581262
return rtn;
12591263
}
1264+
1265+
/**
1266+
* Return the first matching namespace for the provided prefix.
1267+
*/
1268+
function findNs(prefix: string, ...xmlnss: Array<IXmlNs | undefined>): string | undefined {
1269+
for (const xmlns of xmlnss) {
1270+
if (xmlns?.[prefix]) {
1271+
return xmlns[prefix];
1272+
}
1273+
}
1274+
}

test/wsdl-test.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,4 +407,16 @@ describe('WSDL Parser (non-strict)', () => {
407407
done();
408408
});
409409
});
410+
411+
it('should describe correct service input/output when imports have different tns namespaces', function(done) {
412+
soap.createClient(__dirname + '/wsdl/tnsImportConflict/root.wsdl', function(err, client) {
413+
assert.ifError(err);
414+
var description = client.describe();
415+
assert.deepStrictEqual(description.TestService.TestPort.Test, {
416+
input: { val: 'xsd:string' },
417+
output: { val: 'xsd:string' },
418+
});
419+
done();
420+
});
421+
});
410422
});
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<wsdl:definitions
3+
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
4+
xmlns:tns="bar"
5+
targetNamespace="bar">
6+
</wsdl:definitions>
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<wsdl:definitions
3+
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
4+
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
5+
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
6+
xmlns:tns="foo"
7+
targetNamespace="foo">
8+
9+
<wsdl:types>
10+
<xsd:schema targetNamespace="foo" elementFormDefault="qualified">
11+
<xsd:element name="TestElement">
12+
<xsd:complexType>
13+
<xsd:sequence>
14+
<xsd:element name="val" type="xsd:string" minOccurs="0"/>
15+
</xsd:sequence>
16+
</xsd:complexType>
17+
</xsd:element>
18+
</xsd:schema>
19+
</wsdl:types>
20+
21+
<wsdl:message name="TestInputMessage">
22+
<wsdl:part name="params" element="tns:TestElement"/>
23+
</wsdl:message>
24+
25+
<wsdl:message name="TestOutputMessage">
26+
<wsdl:part name="params" element="tns:TestElement"/>
27+
</wsdl:message>
28+
29+
<wsdl:portType name="TestPortType">
30+
<wsdl:operation name="Test">
31+
<wsdl:input message="tns:TestInputMessage"/>
32+
<wsdl:output message="tns:TestOutputMessage"/>
33+
</wsdl:operation>
34+
</wsdl:portType>
35+
36+
<wsdl:binding name="TestBinding" type="tns:TestPortType">
37+
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
38+
<wsdl:operation name="Test">
39+
<soap:operation soapAction="foo/Test"/>
40+
<wsdl:input>
41+
<soap:body use="literal"/>
42+
</wsdl:input>
43+
<wsdl:output>
44+
<soap:body use="literal"/>
45+
</wsdl:output>
46+
</wsdl:operation>
47+
</wsdl:binding>
48+
49+
</wsdl:definitions>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<wsdl:definitions
3+
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
4+
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
5+
xmlns:tns="http://tempuri.org"
6+
name="TestService"
7+
targetNamespace="http://tempuri.org">
8+
9+
<wsdl:import namespace="foo" location="foo.wsdl"/>
10+
<wsdl:import namespace="bar" location="bar.wsdl"/>
11+
12+
<wsdl:service name="TestService">
13+
<wsdl:port name="TestPort" binding="tns:TestBinding">
14+
<soap:address location="http://example.com/TestService"/>
15+
</wsdl:port>
16+
</wsdl:service>
17+
</wsdl:definitions>

0 commit comments

Comments
 (0)