Skip to content

Commit

Permalink
Merge pull request vpulim#241 from godaddy/add-attributes-to-elements
Browse files Browse the repository at this point in the history
Add non xmlns attributes to elements during response parsing
  • Loading branch information
Vinay Pulim committed Feb 15, 2014
2 parents 04b1dc9 + 77cd4c3 commit 3835f9e
Show file tree
Hide file tree
Showing 6 changed files with 215 additions and 0 deletions.
12 changes: 12 additions & 0 deletions lib/wsdl.js
Original file line number Diff line number Diff line change
Expand Up @@ -801,8 +801,11 @@ WSDL.prototype.xmlToObject = function(xml) {

p.on('startElement', function(nsName, attrs) {
var name = splitNSName(nsName).name,
attributeName,
top = stack[stack.length - 1],
topSchema = top.schema,
elementAttributes = {},
hasNonXmlnsAttribute = false,
obj = {};
var originalName = name;

Expand Down Expand Up @@ -853,6 +856,15 @@ WSDL.prototype.xmlToObject = function(xml) {
refs[id] = {hrefs: [], obj: null};
}

//Handle element attributes
for(attributeName in attrs){
if(/^xmlns:?/.test(attributeName))continue;
hasNonXmlnsAttribute = true;
elementAttributes[attributeName] = attrs[attributeName];
}

if(hasNonXmlnsAttribute)obj.attributes = elementAttributes;

if (topSchema && topSchema[name + '[]'])
name = name + '[]';
stack.push({name: originalName, object: obj, schema: topSchema && topSchema[name], id: attrs.id});
Expand Down
43 changes: 43 additions & 0 deletions test/response-parsing-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"use strict";

var assert = require('assert');
var glob = require('glob');
var soap = require('..');
var fs = require('fs');
var path = require('path');

var instance;
var tests = {};

var xmlResponses = glob.sync('response-parsing/*', {cwd:__dirname})
.filter(function(entry){
return fs.statSync(path.resolve(__dirname, entry)).isDirectory();
});

module.exports = {
'Response Parsing':tests
};

//generate the tests
xmlResponses.forEach(function(relativePath){
var dir = path.resolve(__dirname, relativePath);
var xmlResponse = path.resolve(dir, 'response.xml');
var jsonResponse = path.resolve(dir, 'response.json');
var wsdl = path.resolve(dir, 'soap.wsdl');
var testname = path.basename(dir);

tests[testname] = generateTest(xmlResponse, jsonResponse, wsdl);
});

function generateTest(xmlPath, jsonPath, wsdlPath){
return function(done){
soap.createClient(wsdlPath, function(err, client){
var wsdl = client.wsdl;
var responseXml = ""+fs.readFileSync(xmlPath);
var proposedObj = wsdl.xmlToObject(responseXml);
var expectedObj = require(jsonPath);
assert.deepEqual(proposedObj, expectedObj);
done();
});
};
}
10 changes: 10 additions & 0 deletions test/response-parsing/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
This directory contains test cases for sample response parsing. Since node-soap
generates the request XML, we can focus on the response aspect here. This
directory contains child directories that each contain 3 files:


* response.json This is the expected output of parsing response.xml
* response.xml This is what the server is expected to respond back with
* soap.wsdl This is the wsdl used to construct clients

The name of each directory herein should reflect the reason for it's addition.
30 changes: 30 additions & 0 deletions test/response-parsing/attribute-parsing/response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"Body":{
"GetAccountXmlResponse":{
"ResultCode":0,
"AccountXml":{
"Foo": {
"Foo":{
"attributes":{
"PrivateLabelID":"1",
"ResourceID":"034b7ea5-8a04-11e3-9710-0050569575d8",
"IsPastDue":"False",
"IsFree":"True",
"CurrentTreeID":"1091",
"CurrentUnifiedProductID":"70761"
},
"Tree":{
"attributes":{
"TreeID":"1091",
"NodeID":"1091",
"UnifiedProductID":"70761",
"IsFree":"True"
},
"FilteredTransitions":{}
}
}
}
}
}
}
}
34 changes: 34 additions & 0 deletions test/response-parsing/attribute-parsing/response.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
>
<soap:Body>
<GetAccountXmlResponse xmlns="#Foo">
<ResultCode>0</ResultCode>
<AccountXml>
<Foo>
<Foo
PrivateLabelID="1"
ResourceID="034b7ea5-8a04-11e3-9710-0050569575d8"
IsPastDue="False"
IsFree="True"
CurrentTreeID="1091"
CurrentUnifiedProductID="70761"
xmlns=""
>
<Tree
TreeID="1091"
NodeID="1091"
UnifiedProductID="70761"
IsFree="True"
>
<FilteredTransitions />
</Tree>
</Foo>
</Foo>
</AccountXml>
</GetAccountXmlResponse>
</soap:Body>
</soap:Envelope>
86 changes: 86 additions & 0 deletions test/response-parsing/attribute-parsing/soap.wsdl
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<wsdl:definitions
xmlns:s="http://www.w3.org/2001/XMLSchema"
xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns:tns="#Foo"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="#Foo"
>
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="#Foo">
<s:element name="GetAccountXml">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="ResourceID" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="ResourceType" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="IDType" type="s:string"/>
<s:element minOccurs="1" maxOccurs="1" name="TreeID" type="s:int"/>
<s:element minOccurs="1" maxOccurs="1" name="PrivateLabelID" type="s:int"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="GetAccountXmlResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="ResultCode" type="s:int"/>
<s:element minOccurs="0" maxOccurs="1" name="AccountXml">
<s:complexType mixed="true">
<s:sequence>
<s:any/>
</s:sequence>
</s:complexType>
</s:element>
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
</wsdl:types>
<wsdl:message name="GetAccountXmlSoapIn">
<wsdl:part name="parameters" element="tns:GetAccountXml"/>
</wsdl:message>
<wsdl:message name="GetAccountXmlSoapOut">
<wsdl:part name="parameters" element="tns:GetAccountXmlResponse"/>
</wsdl:message>
<wsdl:portType name="ServiceSoap">
<wsdl:operation name="GetAccountXml">
<wsdl:input message="tns:GetAccountXmlSoapIn"/>
<wsdl:output message="tns:GetAccountXmlSoapOut"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="ServiceSoap" type="tns:ServiceSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="GetAccountXml">
<soap:operation soapAction="#Foo/GetAccountXml" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="ServiceSoap12" type="tns:ServiceSoap">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="GetAccountXml">
<soap12:operation soapAction="#Foo/GetAccountXml" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="Service">
<wsdl:port name="ServiceSoap" binding="tns:ServiceSoap">
<soap:address location="http://localhost:1509"/>
</wsdl:port>
<wsdl:port name="ServiceSoap12" binding="tns:ServiceSoap12">
<soap12:address location="http://localhost:1509"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

0 comments on commit 3835f9e

Please sign in to comment.