Comparing version 0.9.5 to 0.10.0
@@ -0,1 +1,5 @@ | ||
0.10.0 / 2015-10-21 | ||
================= | ||
* [FIX] xml namespace/element/type handling. (#756) | ||
0.9.5 / 2015-10-15 | ||
@@ -2,0 +6,0 @@ ================= |
@@ -8,7 +8,2 @@ /* | ||
function findKey(obj, val) { | ||
for (var n in obj) | ||
if (obj[n] === val) | ||
return n; | ||
} | ||
@@ -20,3 +15,3 @@ var HttpClient = require('./http'), | ||
debug = require('debug')('node-soap'), | ||
url = require('url'), | ||
findPrefix = require('./utils').findPrefix, | ||
_ = require('lodash'); | ||
@@ -153,3 +148,3 @@ | ||
soapAction, | ||
alias = findKey(defs.xmlns, ns), | ||
alias = findPrefix(defs.xmlns, ns), | ||
headers = { | ||
@@ -156,0 +151,0 @@ 'Content-Type': "text/xml; charset=utf-8" |
@@ -8,8 +8,2 @@ /* | ||
function findKey(obj, val) { | ||
for (var n in obj) | ||
if (obj[n] === val) | ||
return n; | ||
} | ||
function getDateString(d) { | ||
@@ -30,3 +24,4 @@ function pad(n) { | ||
events = require('events'), | ||
util = require('util'); | ||
util = require('util'), | ||
findPrefix = require('./utils').findPrefix; | ||
@@ -310,3 +305,3 @@ try { | ||
encoding = '', | ||
alias = findKey(defs.xmlns, ns); | ||
alias = findPrefix(defs.xmlns, ns); | ||
var xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + | ||
@@ -313,0 +308,0 @@ "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" " + |
@@ -12,1 +12,22 @@ | ||
var TNS_PREFIX = '__tns__'; // Prefix for targetNamespace | ||
exports.TNS_PREFIX = TNS_PREFIX; | ||
/** | ||
* Find a key from an object based on the value | ||
* @param {Object} Namespace prefix/uri mapping | ||
* @param {*} nsURI value | ||
* @returns {String} The matching key | ||
*/ | ||
exports.findPrefix = function(xmlnsMapping, nsURI) { | ||
for (var n in xmlnsMapping) { | ||
if (n === TNS_PREFIX) continue; | ||
if (xmlnsMapping[n] === nsURI) | ||
return n; | ||
} | ||
}; | ||
496
lib/wsdl.js
@@ -13,2 +13,3 @@ /* | ||
var HttpClient = require('./http'); | ||
var NamespaceContext = require('./nscontext'); | ||
var fs = require('fs'); | ||
@@ -22,2 +23,5 @@ var url = require('url'); | ||
var selectn = require('selectn'); | ||
var utils = require('./utils'); | ||
var TNS_PREFIX = utils.TNS_PREFIX; | ||
var findPrefix = utils.findPrefix; | ||
@@ -59,5 +63,6 @@ var Primitives = { | ||
function splitNSName(nsName) { | ||
function splitQName(nsName) { | ||
var i = typeof nsName === 'string' ? nsName.indexOf(':') : -1; | ||
return i < 0 ? {namespace: 'xmlns', name: nsName} : {namespace: nsName.substring(0, i), name: nsName.substring(i + 1)}; | ||
return i < 0 ? {prefix: TNS_PREFIX, name: nsName} : | ||
{prefix: nsName.substring(0, i), name: nsName.substring(i + 1)}; | ||
} | ||
@@ -110,13 +115,7 @@ | ||
function findKey(obj, val) { | ||
for (var n in obj) | ||
if (obj[n] === val) | ||
return n; | ||
} | ||
var Element = function(nsName, attrs, options) { | ||
var parts = splitNSName(nsName); | ||
var parts = splitQName(nsName); | ||
this.nsName = nsName; | ||
this.namespace = parts.namespace; | ||
this.prefix = parts.prefix; | ||
this.name = parts.name; | ||
@@ -131,3 +130,3 @@ this.children = []; | ||
if (match) { | ||
this.xmlns[match[1] ? match[1] : 'xmlns'] = attrs[key]; | ||
this.xmlns[match[1] ? match[1] : TNS_PREFIX] = attrs[key]; | ||
} | ||
@@ -142,2 +141,6 @@ else { | ||
} | ||
if (this.$targetNamespace !== undefined) { | ||
// Add targetNamespace to the mapping | ||
this.xmlns[TNS_PREFIX] = this.$targetNamespace; | ||
} | ||
}; | ||
@@ -161,3 +164,3 @@ | ||
delete this.nsName; | ||
delete this.namespace; | ||
delete this.prefix; | ||
delete this.name; | ||
@@ -172,3 +175,3 @@ }; | ||
var ChildClass = this.allowedChildren[splitNSName(nsName).name], | ||
var ChildClass = this.allowedChildren[splitQName(nsName).name], | ||
element = null; | ||
@@ -259,5 +262,5 @@ | ||
simpleType: [SimpleTypeElement, 'restriction'], | ||
restriction: [RestrictionElement, 'enumeration choice sequence'], | ||
extension: [ExtensionElement, 'sequence choice'], | ||
choice: [ChoiceElement, 'element choice'], | ||
restriction: [RestrictionElement, 'enumeration all choice sequence'], | ||
extension: [ExtensionElement, 'all sequence choice'], | ||
choice: [ChoiceElement, 'element sequence choice any'], | ||
// group: [GroupElement, 'element group'], | ||
@@ -268,3 +271,3 @@ enumeration: [EnumerationElement, ''], | ||
simpleContent: [SimpleContentElement, 'extension'], | ||
sequence: [SequenceElement, 'element choice any'], | ||
sequence: [SequenceElement, 'element sequence choice any'], | ||
all: [AllElement, 'element choice'], | ||
@@ -494,4 +497,4 @@ | ||
nsName = splitNSName(part.$element); | ||
ns = nsName.namespace; | ||
nsName = splitQName(part.$element); | ||
ns = nsName.prefix; | ||
var schema = definitions.schemas[definitions.xmlns[ns]]; | ||
@@ -538,4 +541,4 @@ this.element = schema.elements[nsName.name]; | ||
if (this.element.$type) { | ||
type = splitNSName(this.element.$type); | ||
var typeNs = schema.xmlns && schema.xmlns[type.namespace] || definitions.xmlns[type.namespace]; | ||
type = splitQName(this.element.$type); | ||
var typeNs = schema.xmlns && schema.xmlns[type.prefix] || definitions.xmlns[type.prefix]; | ||
@@ -575,4 +578,4 @@ if (typeNs) { | ||
assert(part.name === 'part', 'Expected part element'); | ||
nsName = splitNSName(part.$type); | ||
ns = definitions.xmlns[nsName.namespace]; | ||
nsName = splitQName(part.$type); | ||
ns = definitions.xmlns[nsName.prefix]; | ||
type = nsName.name; | ||
@@ -587,3 +590,3 @@ var schemaDefinition = definitions.schemas[ns]; | ||
if (typeof this.parts[part.$name] === 'object') { | ||
this.parts[part.$name].namespace = nsName.namespace; | ||
this.parts[part.$name].prefix = nsName.prefix; | ||
this.parts[part.$name].xmlns = ns; | ||
@@ -601,3 +604,3 @@ } | ||
* object for further use in as first (lookup) `parameterTypeObj` within the `objectToXML` | ||
* method and provides an entry point for the already existing code in `findChildParameterObject`. | ||
* method and provides an entry point for the already existing code in `findChildSchemaObject`. | ||
* | ||
@@ -611,4 +614,4 @@ * @method _createLookupTypeObject | ||
MessageElement.prototype._createLookupTypeObject = function (nsString, xmlns) { | ||
var splittedNSString = splitNSName(nsString), | ||
nsAlias = splittedNSString.namespace, | ||
var splittedNSString = splitQName(nsString), | ||
nsAlias = splittedNSString.prefix, | ||
splittedName = splittedNSString.name.split('#'), | ||
@@ -671,3 +674,3 @@ type = splittedName[0], | ||
} | ||
var messageName = splitNSName(child.$message).name; | ||
var messageName = splitQName(child.$message).name; | ||
var message = definitions.messages[messageName]; | ||
@@ -703,3 +706,3 @@ message.postProcess(definitions); | ||
BindingElement.prototype.postProcess = function(definitions) { | ||
var type = splitNSName(this.$type).name, | ||
var type = splitQName(this.$type).name, | ||
portType = definitions.portTypes[type], | ||
@@ -741,3 +744,3 @@ style = this.style, | ||
continue; | ||
var bindingName = splitNSName(child.$binding).name; | ||
var bindingName = splitQName(child.$binding).name; | ||
var binding = bindings[bindingName]; | ||
@@ -773,3 +776,3 @@ if (binding) { | ||
child instanceof ChoiceElement) { | ||
desc = child.description(definitions); | ||
desc = child.description(definitions, xmlns); | ||
break; | ||
@@ -779,5 +782,5 @@ } | ||
if (desc && this.$base) { | ||
var type = splitNSName(this.$base), | ||
var type = splitQName(this.$base), | ||
typeName = type.name, | ||
ns = xmlns && xmlns[type.namespace] || definitions.xmlns[type.namespace], | ||
ns = xmlns && xmlns[type.prefix] || definitions.xmlns[type.prefix], | ||
schema = definitions.schemas[ns], | ||
@@ -787,3 +790,3 @@ typeElement = schema && ( schema.complexTypes[typeName] || schema.types[typeName] || schema.elements[typeName] ); | ||
desc.getBase = function() { | ||
return typeElement.description(definitions, xmlns); | ||
return typeElement.description(definitions, schema.xmlns); | ||
}; | ||
@@ -806,9 +809,9 @@ return desc; | ||
child instanceof ChoiceElement) { | ||
desc = child.description(definitions); | ||
desc = child.description(definitions, xmlns); | ||
} | ||
} | ||
if (this.$base) { | ||
var type = splitNSName(this.$base), | ||
var type = splitQName(this.$base), | ||
typeName = type.name, | ||
ns = xmlns && xmlns[type.namespace] || definitions.xmlns[type.namespace], | ||
ns = xmlns && xmlns[type.prefix] || definitions.xmlns[type.prefix], | ||
schema = definitions.schemas[ns]; | ||
@@ -824,3 +827,3 @@ | ||
if (typeElement) { | ||
var base = typeElement.description(definitions, xmlns); | ||
var base = typeElement.description(definitions, schema.xmlns); | ||
extend(desc, base); | ||
@@ -880,11 +883,14 @@ } | ||
if (xmlns && xmlns[TNS_PREFIX]) { | ||
this.$targetNamespace = xmlns[TNS_PREFIX]; | ||
} | ||
var type = this.$type || this.$ref; | ||
if (type) { | ||
type = splitNSName(type); | ||
type = splitQName(type); | ||
var typeName = type.name, | ||
ns = xmlns && xmlns[type.namespace] || definitions.xmlns[type.namespace], | ||
ns = xmlns && xmlns[type.prefix] || definitions.xmlns[type.prefix], | ||
schema = definitions.schemas[ns], | ||
typeElement = schema && ( schema.complexTypes[typeName] || schema.types[typeName] || schema.elements[typeName] ); | ||
typeElement = schema && ( this.$type? schema.complexTypes[typeName] || schema.types[typeName] : schema.elements[typeName] ); | ||
if(ns && definitions.schemas[ns]) { | ||
if (ns && definitions.schemas[ns]) { | ||
xmlns = definitions.schemas[ns].xmlns; | ||
@@ -917,3 +923,3 @@ } | ||
if (typeof elem === 'object') { | ||
elem.targetNSAlias = type.namespace; | ||
elem.targetNSAlias = type.prefix; | ||
elem.targetNamespace = ns; | ||
@@ -1232,3 +1238,3 @@ } | ||
var name = splitNSName(nsName).name, | ||
var name = splitQName(nsName).name, | ||
attributeName, | ||
@@ -1293,3 +1299,3 @@ top = stack[stack.length - 1], | ||
if(/^xmlns:|^xmlns$/.test(attributeName)){ | ||
xmlns[splitNSName(attributeName).name] = attrs[attributeName]; | ||
xmlns[splitQName(attributeName).name] = attrs[attributeName]; | ||
continue; | ||
@@ -1302,4 +1308,4 @@ } | ||
for(attributeName in elementAttributes){ | ||
var res = splitNSName(attributeName); | ||
if(res.name === 'nil' && xmlns[res.namespace] === 'http://www.w3.org/2001/XMLSchema-instance'){ | ||
var res = splitQName(attributeName); | ||
if(res.name === 'nil' && xmlns[res.prefix] === 'http://www.w3.org/2001/XMLSchema-instance'){ | ||
hasNilAttribute = true; | ||
@@ -1316,4 +1322,11 @@ break; | ||
if (xsiType) { | ||
var type = splitNSName(xsiType); | ||
var typeDef = self.findParameterObject(xmlns[type.namespace], type.name); | ||
var type = splitQName(xsiType); | ||
var typeURI; | ||
if (type.prefix === TNS_PREFIX) { | ||
// In case of xsi:type = "MyType" | ||
typeURI = xmlns[type.prefix] || xmlns.xmlns; | ||
} else { | ||
typeURI = xmlns[type.prefix]; | ||
} | ||
var typeDef = self.findSchemaObject(typeURI, type.name); | ||
if (typeDef) { | ||
@@ -1335,3 +1348,3 @@ xsiTypeSchema = typeDef.description(self.definitions); | ||
topSchema = top.schema, | ||
name = splitNSName(nsName).name; | ||
name = splitQName(nsName).name; | ||
@@ -1346,3 +1359,2 @@ if (typeof cur.schema === 'string' && (cur.schema === 'string' || cur.schema.split(':')[1] === 'string')) { | ||
if (topSchema && topSchema[name + '[]']) { | ||
@@ -1392,3 +1404,3 @@ if (!topObject[name]) | ||
var top = stack[stack.length - 1]; | ||
var name = splitNSName(top.schema).name, | ||
var name = splitQName(top.schema).name, | ||
value; | ||
@@ -1451,37 +1463,55 @@ if (name === 'int' || name === 'integer') { | ||
WSDL.prototype.findParameterObject = function(xmlns, parameterType) { | ||
if (!xmlns || !parameterType) { | ||
/** | ||
* Look up a XSD type or element by namespace URI and name | ||
* @param {String} nsURI Namespace URI | ||
* @param {String} qname Local or qualified name | ||
* @returns {*} The XSD type/element definition | ||
*/ | ||
WSDL.prototype.findSchemaObject = function(nsURI, qname) { | ||
if (!nsURI || !qname) { | ||
return null; | ||
} | ||
var parameterTypeObj = null; | ||
var def = null; | ||
if (this.definitions.schemas) { | ||
var schema = this.definitions.schemas[xmlns]; | ||
var schema = this.definitions.schemas[nsURI]; | ||
if (schema) { | ||
if (parameterType.indexOf(':') !== -1) { | ||
parameterType = parameterType.substring(parameterType.indexOf(':') + 1, parameterType.length); | ||
if (qname.indexOf(':') !== -1) { | ||
qname = qname.substring(qname.indexOf(':') + 1, qname.length); | ||
} | ||
// if the client passed an input element which has a `$lookupType` property instead of `$type` | ||
// the `parameterTypeObj` is found in `schema.elements`. | ||
parameterTypeObj = schema.complexTypes[parameterType] || schema.elements[parameterType]; | ||
// the `def` is found in `schema.elements`. | ||
def = schema.complexTypes[qname] || schema.types[qname] || schema.elements[qname]; | ||
} | ||
} | ||
return parameterTypeObj; | ||
return def; | ||
}; | ||
WSDL.prototype.objectToDocumentXML = function(name, params, ns, xmlns, type) { | ||
/** | ||
* Create document style xml string from the parameters | ||
* @param {String} name | ||
* @param {*} params | ||
* @param {String} nsPrefix | ||
* @param {String} nsURI | ||
* @param {String} type | ||
*/ | ||
WSDL.prototype.objectToDocumentXML = function(name, params, nsPrefix, nsURI, type) { | ||
var args = {}; | ||
args[name] = params; | ||
var parameterTypeObj = type ? this.findParameterObject(xmlns, type) : null; | ||
if (this.namespaceNumber) { | ||
this.namespaceNumber = 0; | ||
} | ||
return this.objectToXML(args, null, ns, xmlns, true, null, parameterTypeObj); | ||
var parameterTypeObj = type ? this.findSchemaObject(nsURI, type) : null; | ||
return this.objectToXML(args, null, nsPrefix, nsURI, true, null, parameterTypeObj); | ||
}; | ||
WSDL.prototype.objectToRpcXML = function(name, params, namespace, xmlns) { | ||
var self = this; | ||
/** | ||
* Create RPC style xml string from the parameters | ||
* @param {String} name | ||
* @param {*} params | ||
* @param {String} nsPrefix | ||
* @param {String} nsURI | ||
* @returns {string} | ||
*/ | ||
WSDL.prototype.objectToRpcXML = function(name, params, nsPrefix, nsURI) { | ||
var parts = []; | ||
@@ -1491,6 +1521,6 @@ var defs = this.definitions; | ||
namespace = namespace || findKey(defs.xmlns, xmlns); | ||
xmlns = xmlns || defs.xmlns[namespace]; | ||
namespace = namespace === 'xmlns' ? '' : (namespace + ':'); | ||
parts.push(['<', namespace, name, '>'].join('')); | ||
nsPrefix = nsPrefix || findPrefix(defs.xmlns, nsURI); | ||
nsURI = nsURI || defs.xmlns[nsPrefix]; | ||
nsPrefix = nsPrefix === TNS_PREFIX ? '' : (nsPrefix + ':'); | ||
parts.push(['<', nsPrefix, name, '>'].join('')); | ||
@@ -1501,7 +1531,7 @@ for (var key in params) { | ||
parts.push(['<', key, '>'].join('')); | ||
parts.push((typeof value === 'object') ? this.objectToXML(value, key, namespace, xmlns) : xmlEscape(value)); | ||
parts.push((typeof value === 'object') ? this.objectToXML(value, key, nsPrefix, nsURI) : xmlEscape(value)); | ||
parts.push(['</', key, '>'].join('')); | ||
} | ||
} | ||
parts.push(['</', namespace, name, '>'].join('')); | ||
parts.push(['</', nsPrefix, name, '>'].join('')); | ||
@@ -1517,17 +1547,17 @@ return parts.join(''); | ||
* an element). | ||
* @param {String} namespace the namespace prefix of the object I.E. xsd. | ||
* @param {String} xmlns the full namespace of the object I.E. http://w3.org/schema. | ||
* @param {String} nsPrefix the namespace prefix of the object I.E. xsd. | ||
* @param {String} nsURI the full namespace of the object I.E. http://w3.org/schema. | ||
* @param {Boolean} isFirst whether or not this is the first item being traversed. | ||
* @param {?} xmlnsAttr | ||
* @param {?} parameterTypeObject | ||
* @param {?} ancestorXmlns | ||
* @param {NamespaceContext} nsContext Namespace context | ||
*/ | ||
WSDL.prototype.objectToXML = function(obj, name, namespace, xmlns, isFirst, xmlnsAttr, parameterTypeObject, ancestorXmlns) { | ||
WSDL.prototype.objectToXML = function(obj, name, nsPrefix, nsURI, isFirst, xmlnsAttr, schemaObject, nsContext) { | ||
var self = this; | ||
var schema = this.definitions.schemas[xmlns]; | ||
var schema = this.definitions.schemas[nsURI]; | ||
var parentNamespace = namespace ? namespace.parent : undefined; | ||
if(typeof parentNamespace !== 'undefined') { | ||
//we got the parentNamespace for our array. setting the namespace-variable back to the current namespace string | ||
namespace = namespace.current; | ||
var parentNsPrefix = nsPrefix ? nsPrefix.parent : undefined; | ||
if(typeof parentNsPrefix !== 'undefined') { | ||
//we got the parentNsPrefix for our array. setting the namespace-variable back to the current namespace string | ||
nsPrefix = nsPrefix.current; | ||
} | ||
@@ -1538,16 +1568,21 @@ | ||
var parts = []; | ||
var prefixNamespace = (namespace || qualified) && namespace !== 'xmlns'; | ||
var prefixNamespace = (nsPrefix || qualified) && nsPrefix !== TNS_PREFIX; | ||
var xmlnsAttrib = ''; | ||
if (xmlns && isFirst) { | ||
if (nsURI && isFirst) { | ||
if (prefixNamespace && this.options.ignoredNamespaces.indexOf(namespace) === -1) { | ||
if (prefixNamespace && this.options.ignoredNamespaces.indexOf(nsPrefix) === -1) { | ||
// resolve the prefix namespace | ||
xmlnsAttrib += ' xmlns:' + namespace + '="' + xmlns + '"'; | ||
xmlnsAttrib += ' xmlns:' + nsPrefix + '="' + nsURI + '"'; | ||
} | ||
// only add default namespace if the schema elementFormDefault is qualified | ||
if (qualified || soapHeader) xmlnsAttrib += ' xmlns="' + xmlns + '"'; | ||
if (qualified || soapHeader) xmlnsAttrib += ' xmlns="' + nsURI + '"'; | ||
} | ||
var ancXmlns = ancestorXmlns ? ancestorXmlns : new Array(xmlns); | ||
if (!nsContext) { | ||
nsContext = new NamespaceContext(); | ||
nsContext.declareNamespace(nsPrefix, nsURI); | ||
} else { | ||
nsContext.pushContext(); | ||
} | ||
@@ -1560,16 +1595,18 @@ // explicitly use xmlns attribute if available | ||
var ns = ''; | ||
if (prefixNamespace && ((qualified || isFirst) || soapHeader) && this.options.ignoredNamespaces.indexOf(namespace) === -1) { | ||
if (prefixNamespace && ((qualified || isFirst) || soapHeader) && this.options.ignoredNamespaces.indexOf(nsPrefix) === -1) { | ||
// prefix element | ||
ns = namespace.indexOf(":") === -1 ? namespace + ':' : namespace; | ||
ns = nsPrefix.indexOf(":") === -1 ? nsPrefix + ':' : nsPrefix; | ||
} | ||
var i, n; | ||
// start building out XML string. | ||
if (Array.isArray(obj)) { | ||
for (var i = 0, item; item = obj[i]; i++) { | ||
var arrayAttr = self.processAttributes(item), | ||
correctOuterNamespace = parentNamespace || ns; //using the parent namespace if given | ||
for (i = 0, n = obj.length; i < n; i++) { | ||
var item = obj[i]; | ||
var arrayAttr = self.processAttributes(item, nsContext), | ||
correctOuterNsPrefix = parentNsPrefix || ns; //using the parent namespace prefix if given | ||
parts.push(['<', correctOuterNamespace, name, arrayAttr, xmlnsAttrib, '>'].join('')); | ||
parts.push(self.objectToXML(item, name, namespace, xmlns, false, null, parameterTypeObject, ancXmlns)); | ||
parts.push(['</', correctOuterNamespace, name, '>'].join('')); | ||
parts.push(['<', correctOuterNsPrefix, name, arrayAttr, xmlnsAttrib, '>'].join('')); | ||
parts.push(self.objectToXML(item, name, nsPrefix, nsURI, false, null, schemaObject, nsContext)); | ||
parts.push(['</', correctOuterNsPrefix, name, '>'].join('')); | ||
} | ||
@@ -1595,3 +1632,3 @@ } else if (typeof obj === 'object') { | ||
var attr = self.processAttributes(child); | ||
var attr = self.processAttributes(child, nsContext); | ||
@@ -1608,3 +1645,3 @@ var value = ''; | ||
if (isFirst) { | ||
value = self.objectToXML(child, name, namespace, xmlns, false, null, parameterTypeObject, ancXmlns); | ||
value = self.objectToXML(child, name, nsPrefix, nsURI, false, null, schemaObject, nsContext); | ||
} else { | ||
@@ -1614,59 +1651,92 @@ | ||
if (schema) { | ||
var childParameterTypeObject = self.findChildParameterObject(parameterTypeObject, name); | ||
var childSchemaObject = self.findChildSchemaObject(schemaObject, name); | ||
//find sub namespace if not a primitive | ||
if (childParameterTypeObject && | ||
((childParameterTypeObject.$type && (childParameterTypeObject.$type.indexOf('xsd') === -1)) || | ||
childParameterTypeObject.$ref)) { | ||
if (childSchemaObject && | ||
((childSchemaObject.$type && (childSchemaObject.$type.indexOf('xsd:') === -1)) || | ||
childSchemaObject.$ref || childSchemaObject.$name)) { | ||
/*if the base name space of the children is not in the ingoredSchemaNamspaces we use it. | ||
This is because in some services the child nodes do not need the baseNameSpace. | ||
*/ | ||
if(childParameterTypeObject.$baseNameSpace && !this.options.ignoreBaseNameSpaces) { | ||
ns = childParameterTypeObject.$baseNameSpace + ':'; | ||
} | ||
var childParameterType = childParameterTypeObject.$type || childParameterTypeObject.$ref; | ||
var childNamespace = ''; | ||
var childNsPrefix = ''; | ||
var childName = ''; | ||
if (childParameterType.indexOf(':') !== -1) { | ||
childNamespace = childParameterType.substring(0, childParameterType.indexOf(':')); | ||
childName = childParameterType.substring(childParameterType.indexOf(':') + 1); | ||
} | ||
var childXmlns = schema.xmlns[childNamespace] || self.definitions.xmlns[childNamespace]; | ||
var childNsURI; | ||
var childXmlnsAttrib = ''; | ||
if ((ancXmlns.indexOf(childXmlns) === -1) && (childXmlns)) { | ||
childXmlnsAttrib = ' xmlns:' + childNamespace + '="' + childXmlns+ '"'; | ||
if ((childXmlns)) { | ||
ancXmlns.push(childXmlns); | ||
var elementQName = childSchemaObject.$ref || childSchemaObject.$name; | ||
if (elementQName) { | ||
elementQName = splitQName(elementQName); | ||
childName = elementQName.name; | ||
if (elementQName.prefix === TNS_PREFIX) { | ||
// Local element | ||
childNsURI = childSchemaObject.$targetNamespace; | ||
childNsPrefix = nsContext.registerNamespace(childNsURI); | ||
for (i = 0, n = this.ignoredNamespaces.length; i < n; i++) { | ||
if (this.ignoredNamespaces[i] === childNsPrefix) { | ||
childNsPrefix = nsPrefix; | ||
break; | ||
} | ||
} | ||
} else { | ||
childNsPrefix = elementQName.prefix; | ||
for (i = 0, n = this.ignoredNamespaces.length; i < n; i++) { | ||
if (this.ignoredNamespaces[i] === childNsPrefix) { | ||
childNsPrefix = nsPrefix; | ||
break; | ||
} | ||
} | ||
childNsURI = schema.xmlns[childNsPrefix] || self.definitions.xmlns[childNsPrefix]; | ||
} | ||
var unqualified = false; | ||
// Check qualification form for local elements | ||
if (childSchemaObject.$name && childSchemaObject.targetNamespace === undefined) { | ||
if (childSchemaObject.$form === 'unqualified') { | ||
unqualified = true; | ||
} else if (childSchemaObject.$form === 'qualified') { | ||
unqualified = false; | ||
} else { | ||
unqualified = schema.$elementFormDefault === 'unqualified'; | ||
} | ||
} | ||
if (unqualified) { | ||
childNsPrefix = ''; | ||
} | ||
if (childNsURI && childNsPrefix) { | ||
if (nsContext.declareNamespace(childNsPrefix, childNsURI)) { | ||
childXmlnsAttrib = ' xmlns:' + childNsPrefix + '="' + childNsURI + '"'; | ||
xmlnsAttrib += childXmlnsAttrib; | ||
} | ||
} | ||
} | ||
// There is matching element ref | ||
if (childParameterTypeObject.$ref) { | ||
ns = childNamespace ? childNamespace + ':' : ''; | ||
xmlnsAttrib = childXmlnsAttrib; | ||
} | ||
var completeChildParameterTypeObject; | ||
if (childParameterTypeObject.$type) { | ||
completeChildParameterTypeObject = | ||
self.findChildParameterObjectFromSchema(childName, childXmlns) || | ||
childParameterTypeObject; | ||
var resolvedChildSchemaObject; | ||
if (childSchemaObject.$type) { | ||
var typeQName = splitQName(childSchemaObject.$type); | ||
var typePrefix = typeQName.prefix; | ||
var typeURI = schema.xmlns[typePrefix] || self.definitions.xmlns[typePrefix]; | ||
childNsURI = typeURI; | ||
if (typeURI !== 'http://www.w3.org/2001/XMLSchema') { | ||
// Add the prefix/namespace mapping, but not declare it | ||
nsContext.addNamespace(typeQName.prefix, typeURI); | ||
} | ||
resolvedChildSchemaObject = | ||
self.findSchemaType(typeQName.name, typeURI) || childSchemaObject; | ||
} else { | ||
completeChildParameterTypeObject = | ||
self.findParameterObject(childXmlns, childName) || | ||
childParameterTypeObject; | ||
resolvedChildSchemaObject = | ||
self.findSchemaObject(childNsURI, childName) || childSchemaObject; | ||
} | ||
for(var ignoredNamespacesIndex = 0, ignoredNamespacesLength = this.ignoredNamespaces.length; ignoredNamespacesIndex < ignoredNamespacesLength; ignoredNamespacesIndex++) { | ||
if(this.ignoredNamespaces[ignoredNamespacesIndex] === childNamespace) { | ||
childNamespace = namespace; | ||
break; | ||
} | ||
if (childSchemaObject.$baseNameSpace && this.options.ignoreBaseNameSpaces) { | ||
childNsPrefix = nsPrefix; | ||
childNsURI = nsURI; | ||
} | ||
ns = childNsPrefix ? childNsPrefix + ':' : ''; | ||
if(Array.isArray(child)) { | ||
//for arrays, we need to remember the current namespace | ||
childNamespace = { | ||
current: childNamespace, | ||
childNsPrefix = { | ||
current: childNsPrefix, | ||
parent: ns | ||
@@ -1676,14 +1746,20 @@ }; | ||
value = self.objectToXML(child, name, childNamespace, childXmlns, false, childXmlnsAttrib, completeChildParameterTypeObject, ancXmlns); | ||
} else if (obj[self.options.attributesKey] && obj[self.options.attributesKey].xsi_type) { //if parent object has complex type defined and child not found in parent | ||
var completeChildParamTypeObject = self.findChildParameterObjectFromSchema(obj[self.options.attributesKey].xsi_type.type, obj[self.options.attributesKey].xsi_type.xmlns); | ||
value = self.objectToXML(child, name, childNsPrefix, childNsURI, | ||
false, null, resolvedChildSchemaObject, nsContext); | ||
} else if (obj[self.options.attributesKey] && obj[self.options.attributesKey].xsi_type) { | ||
//if parent object has complex type defined and child not found in parent | ||
var completeChildParamTypeObject = self.findChildSchemaObject( | ||
obj[self.options.attributesKey].xsi_type.type, | ||
obj[self.options.attributesKey].xsi_type.xmlns); | ||
nonSubNameSpace = obj[self.options.attributesKey].xsi_type.namespace + ':'; | ||
ancXmlns.push(obj[self.options.attributesKey].xsi_type.xmlns); | ||
value = self.objectToXML(child, name, obj[self.options.attributesKey].xsi_type.namespace, obj[self.options.attributesKey].xsi_type.xmlns, false, null, null, ancXmlns); | ||
nonSubNameSpace = obj[self.options.attributesKey].xsi_type.prefix + ':'; | ||
nsContext.addNamespace(obj[self.options.attributesKey].xsi_type.prefix, | ||
obj[self.options.attributesKey].xsi_type.xmlns); | ||
value = self.objectToXML(child, name, obj[self.options.attributesKey].xsi_type.prefix, | ||
obj[self.options.attributesKey].xsi_type.xmlns, false, null, null, nsContext); | ||
} else { | ||
value = self.objectToXML(child, name, namespace, xmlns, false, null, null, ancXmlns); | ||
value = self.objectToXML(child, name, nsPrefix, nsURI, false, null, null, nsContext); | ||
} | ||
} else { | ||
value = self.objectToXML(child, name, namespace, xmlns, false, null, null, ancXmlns); | ||
value = self.objectToXML(child, name, nsPrefix, nsURI, false, null, null, nsContext); | ||
} | ||
@@ -1694,3 +1770,4 @@ } | ||
if (!Array.isArray(child)) { | ||
parts.push(['<', nonSubNameSpace || ns, name, attr, xmlnsAttrib, (child === null ? ' xsi:nil="true"' : ''), '>'].join('')); | ||
parts.push(['<', nonSubNameSpace || ns, name, attr, xmlnsAttrib, | ||
(child === null ? ' xsi:nil="true"' : ''), '>'].join('')); | ||
} | ||
@@ -1706,7 +1783,7 @@ | ||
} | ||
nsContext.popContext(); | ||
return parts.join(''); | ||
}; | ||
WSDL.prototype.processAttributes = function(child) { | ||
var self = this; | ||
WSDL.prototype.processAttributes = function(child, nsContext) { | ||
var attr = ''; | ||
@@ -1718,27 +1795,28 @@ | ||
if (child[this.options.attributesKey] && child[this.options.attributesKey].xsi_type) { | ||
var xsiType = child[this.options.attributesKey].xsi_type; | ||
var attrObj = child[this.options.attributesKey]; | ||
if (attrObj && attrObj.xsi_type) { | ||
var xsiType = attrObj.xsi_type; | ||
var prefix = xsiType.prefix || xsiType.namespace; | ||
// Generate a new namespace for complex extension if one not provided | ||
if (!xsiType.namespace) { | ||
if (self.namespaceNumber) { | ||
self.namespaceNumber++; | ||
} else { | ||
self.namespaceNumber = 1; | ||
} | ||
xsiType.namespace = 'ns' + self.namespaceNumber; | ||
if (!prefix) { | ||
prefix = nsContext.registerNamespace(xsiType.xmlns); | ||
} else { | ||
nsContext.declareNamespace(prefix, xsiType.xmlns); | ||
} | ||
xsiType.prefix = prefix; | ||
} | ||
if (child[this.options.attributesKey]) { | ||
for (var attrKey in child[this.options.attributesKey]) { | ||
if (attrObj) { | ||
for (var attrKey in attrObj) { | ||
//handle complex extension separately | ||
if (attrKey === 'xsi_type') { | ||
var attrValue = child[this.options.attributesKey][attrKey]; | ||
attr += ' xsi:type="' + attrValue.namespace + ':' + attrValue.type + '"'; | ||
attr += ' xmlns:' + attrValue.namespace + '="' + attrValue.xmlns + '"'; | ||
var attrValue = attrObj[attrKey]; | ||
attr += ' xsi:type="' + attrValue.prefix + ':' + attrValue.type + '"'; | ||
attr += ' xmlns:' + attrValue.prefix + '="' + attrValue.xmlns + '"'; | ||
continue; | ||
} else { | ||
attr += ' ' + attrKey + '="' + xmlEscape(child[this.options.attributesKey][attrKey]) + '"'; | ||
attr += ' ' + attrKey + '="' + xmlEscape(attrObj[attrKey]) + '"'; | ||
} | ||
@@ -1751,8 +1829,14 @@ } | ||
WSDL.prototype.findChildParameterObjectFromSchema = function(name, xmlns) { | ||
if (!this.definitions.schemas || !name || !xmlns) { | ||
/** | ||
* Look up a schema type definition | ||
* @param name | ||
* @param nsURI | ||
* @returns {*} | ||
*/ | ||
WSDL.prototype.findSchemaType = function(name, nsURI) { | ||
if (!this.definitions.schemas || !name || !nsURI) { | ||
return null; | ||
} | ||
var schema = this.definitions.schemas[xmlns]; | ||
var schema = this.definitions.schemas[nsURI]; | ||
if (!schema || !schema.complexTypes) { | ||
@@ -1765,3 +1849,3 @@ return null; | ||
WSDL.prototype.findChildParameterObject = function(parameterTypeObj, childName) { | ||
WSDL.prototype.findChildSchemaObject = function(parameterTypeObj, childName) { | ||
if (!parameterTypeObj || !childName) { | ||
@@ -1793,3 +1877,3 @@ return null; | ||
if (object.$ref) { | ||
ref = splitNSName(object.$ref); | ||
ref = splitQName(object.$ref); | ||
if (ref.name === childName) { | ||
@@ -1800,5 +1884,19 @@ return object; | ||
var childNsURI; | ||
if (object.$type) { | ||
var typeInfo = splitQName(object.$type); | ||
if (typeInfo.prefix === TNS_PREFIX) { | ||
childNsURI = parameterTypeObj.$targetNamespace; | ||
} else { | ||
childNsURI = this.definitions.xmlns[typeInfo.prefix]; | ||
} | ||
var typeDef = this.findSchemaType(typeInfo.name, childNsURI); | ||
if (typeDef) { | ||
return this.findChildSchemaObject(typeDef, childName); | ||
} | ||
} | ||
if (object.children) { | ||
for (i = 0, child; child = object.children[i]; i++) { | ||
found = this.findChildParameterObject(child, childName); | ||
found = this.findChildSchemaObject(child, childName); | ||
if (found) { | ||
@@ -1809,9 +1907,10 @@ break; | ||
if (child.$base) { | ||
var childNameSpace = child.$base.substr(0, child.$base.indexOf(':')), | ||
childXmlns = this.definitions.xmlns[childNameSpace]; | ||
var baseQName = splitQName(child.$base); | ||
var childNameSpace = baseQName.prefix === TNS_PREFIX ? '' : baseQName.prefix; | ||
childNsURI = this.definitions.xmlns[baseQName.prefix]; | ||
var foundBase = this.findChildParameterObjectFromSchema(child.$base.substr(child.$base.indexOf(':') + 1), childXmlns); | ||
var foundBase = this.findSchemaType(baseQName.name, childNsURI); | ||
if (foundBase) { | ||
found = this.findChildParameterObject(foundBase, childName); | ||
found = this.findChildSchemaObject(foundBase, childName); | ||
@@ -1858,3 +1957,3 @@ if (found) { | ||
} else { | ||
name = splitNSName(nsName).name; | ||
name = splitQName(nsName).name; | ||
if (name === 'definitions') { | ||
@@ -1907,3 +2006,3 @@ root = new DefinitionsElement(nsName, attrs, options); | ||
for (var alias in xmlns) { | ||
if (alias === '' || alias === 'xmlns') | ||
if (alias === '' || alias === TNS_PREFIX) | ||
continue; | ||
@@ -1933,24 +2032,20 @@ var ns = xmlns[alias]; | ||
/* | ||
Have another function to load previous WSDLs as we | ||
don't want this to be invoked externally (expect for tests) | ||
This will attempt to fix circular dependencies with XSD files, | ||
Given | ||
file.wsdl | ||
xs:import namespace="A" schemaLocation: A.xsd | ||
A.xsd | ||
xs:import namespace="B" schemaLocation: B.xsd | ||
B.xsd | ||
xs:import namespace="A" schemaLocation: A.xsd | ||
file.wsdl will start loading, import A, then A will import B, which will then import A | ||
Because A has already started to load previously it will be returned right away and | ||
have an internal circular reference | ||
B would then complete loading, then A, then file.wsdl | ||
By the time file A starts processing its includes its definitions will be already loaded, | ||
this is the only thing that B will depend on when "opening" A | ||
*/ | ||
/* | ||
* Have another function to load previous WSDLs as we | ||
* don't want this to be invoked externally (expect for tests) | ||
* This will attempt to fix circular dependencies with XSD files, | ||
* Given | ||
* - file.wsdl | ||
* - xs:import namespace="A" schemaLocation: A.xsd | ||
* - A.xsd | ||
* - xs:import namespace="B" schemaLocation: B.xsd | ||
* - B.xsd | ||
* - xs:import namespace="A" schemaLocation: A.xsd | ||
* file.wsdl will start loading, import A, then A will import B, which will then import A | ||
* Because A has already started to load previously it will be returned right away and | ||
* have an internal circular reference | ||
* B would then complete loading, then A, then file.wsdl | ||
* By the time file A starts processing its includes its definitions will be already loaded, | ||
* this is the only thing that B will depend on when "opening" A | ||
*/ | ||
function open_wsdl_recursive(uri, options, callback) { | ||
@@ -1972,3 +2067,2 @@ var fromCache; | ||
function open_wsdl(uri, options, callback) { | ||
if (typeof options === 'function') { | ||
@@ -1975,0 +2069,0 @@ callback = options; |
{ | ||
"name": "soap", | ||
"version": "0.9.5", | ||
"version": "0.10.0", | ||
"description": "A minimal node SOAP client", | ||
@@ -5,0 +5,0 @@ "engines": { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
135342
23
2937