/*
FARGOS Development, LLC Sample Programs
Copyright (C) 2002 FARGOS Development, LLC. All rights reserved.
mailto:support@fargos.net for assistance.
NOTE: in the future, enhanced versions of these classes may be added to
the FARGOS/VISTA Object Management Environment core within the Standard
namespace. Developers can avoid any potential conflict if they specify
an explicit namespace when creating instances of the sample classes.
*/
%include
class XMLsupport {
/*!
The class class=XMLsupport provides an inheritable set of utility
functions that applications working with XML documents find useful. See
class=WSDL and class=SOAPservice for examples.
!*/
} inherits from Object;
XMLsupport:create() {}
XMLsupport:delete() {}
XMLsupport:_convertToAssoc(array elem)
{
assoc result;
int i;
for(i=3;indexExists(elem, i) != 0;i+=2) {
result[elem[i]] = elem[i + 1];
}
return (result);
}
XMLsupport:_mapToOIL2type(string xmlType)
{
if (xmlType == "xsd:string") return ("string");
if (xmlType == "xsd:base64Binary") return ("string");
if (xmlType == "xsd:int") return ("int");
if (xmlType == "xsd:boolean") return ("int");
display("Unrecognized type ", xmlType, "\n");
return ("any");
}
XMLsupport:_isArray(array elem)
{
int result;
any subElem;
assoc attr;
//display("isArray elem=",elem);
//display("elem[1]=",elem[1],"\n");
if ((elem[1] == "xsd:complexContent") || (elem[1] == "xsd:complexType")) {
for subElem in elem[0] do {
result = call "_isArray"(subElem);
return (result);
}
}
attr = call "_convertToAssoc"(elem);
if (elem[1] == "xsd:restriction") {
if (attr["base"] == "soapenc:Array") return (1);
if (attr["base"] == "xsd:array") return (1);
}
if (elem[1] == "xsd:attribute") {
if (attr["ref"] == "soapenc:arrayType") return (1);
}
return (0);
}
XMLsupport:convertBasicTypeToXML(any data, string elementName,
string xmlTypeName)
{
set lines;
lines += "\t<";
lines += elementName;
lines += " xsi:type=\"";
lines += xmlTypeName;
lines += "\">";
// TO DO: handle conversion of complex types...
if (xmlTypeName == "xsd:base64Binary") {
lines = asciiToBase64(data, 0);
} else if (xmlTypeName == "xsd:boolean") {
if (data == 0) {
lines += "false";
} else {
lines += "true";
}
} else {
lines += makeAsString(data);
}
lines += "";
lines += elementName;
lines += ">\n";
return (lines);
}
class WSDLtoOIL2 {
/*!
Compiles a Web Services Description Language file into an OIL2 source
file. The resulting class implements methods for accessing SOAP-based
services.
!*/
string wsdlDoc;
string outputFileSpec;
string className;
assoc messageDefs;
assoc typeDefs;
assoc bindingDefs;
assoc portTypeDefs;
} inherits from XMLsupport;
WSDLtoOIL2:create(string sourceFile, optional string outFileName)
{
/*!
The sourceFile argument identifies the source of
the Web Services Description File. It is passed to an class=IOobject; however,
if no scheme is specified, a "file:" prefix is added.
If a "file:" scheme is used, a ",r" suffix will be added if needed.
The optional outFileName can be used to specify the output file.
If not provide, a default file name will be derived from the
name of the service by adding a "cl" prefix and a ".oil" suffix.
After processing the source file, a class=WSDLtoOIL2 object automatically
deletes itself.
!*/
oid fileObj;
assoc acl;
any xml;
string fileName;
fileName = sourceFile;
if (findSubstring(fileName, ":") == -1) { // no scheme
fileName = "file:" + fileName;
}
if (findSubstring(fileName, "file:") == 0) {
if (findSubstring(fileName, ",r") == -1) {
fileName += ",r";
}
}
if (typeOf(outFileName) == string) {
outputFileSpec = outFileName;
}
acl = makeDefaultACL();
fileObj = send "createObject"("IOobject", acl, fileName)
to ObjectCreator;
wsdlDoc = send "readBytes"(-1) to fileObj;
send "deleteYourself" to fileObj;
xml = parseXML(wsdlDoc);
display("typeOf xml=", typeOf(xml), "\n");
display("XML parse=", xml);
call "outputCode"(xml);
send "deleteYourself" to thisObject;
}
WSDLtoOIL2:delete() {}
WSDLtoOIL2:_getEncodeMethodName(string xmlType)
{
// default
display("type name\n");
return ("convertBasicTypeToXML");
}
WSDLtoOIL2:_getDecodeMethodName(string xmlType)
{
// default
display("type name\n");
return ("convertBasicTypeToXML");
}
WSDLtoOIL2:outputCode(array xml)
{
array elem;
display("outputCode\n");
if (xml[1] != "definitions") {
display("Not a definitions\n");
return (-1);
}
for elem in xml[0] do {
if (elem[1] == "documentation") {
}
if (elem[1] == "types") {
call "_noteTypes"(elem);
}
if (elem[1] == "message") {
call "_noteMessage"(elem);
}
if (elem[1] == "portType") {
call "_notePortType"(elem);
}
if (elem[1] == "binding") {
call "_noteBinding"(elem);
}
if (elem[1] == "service") {
call "_noteService"(elem);
}
}
return (0);
}
WSDLtoOIL2:_noteService(array elem)
{
int rc, i;
array portElem, typeRec;
assoc attr, acl;
oid outputFile;
set lines;
any messLines;
display("noteService\n");
attr = call "_convertToAssoc"(elem);
if (length(outputFileSpec) == 0) {
outputFileSpec = makeAsString("file:cl", attr["name"],".oil,cwt");
}
if (findSubstring(outputFileSpec, ":") == -1) {
outputFileSpec = "file:" + outputFileSpec;
}
if (findSubstring(outputFileSpec, ",") == -1) {
outputFileSpec += ",cwt";
}
acl = makeDefaultACL();
outputFile = send "createObject"("IOobject", acl, outputFileSpec)
to ObjectCreator;
lines += "// WARNING: automatically generated by the OIL2 class WSDLtoOIL2\n";
lines += "%include \n\n";
className = attr["name"];
for portElem in elem[0] do {
messLines = call "_outputPortWithBinding"(portElem);
lines |= messLines;
}
for (i=nextIndex(typeDefs,0);i != 0;i=nextIndex(typeDefs,i)) {
typeRec = typeDefs[i];
messLines = call "_outputComplexDecodeMethod"(typeRec);
lines |= messLines;
}
lines += "// END OF GENERATED CODE\n";
display("LINES count=", elementCount(lines),"\n");
rc = send "writeVectorOfBytes"(0, lines) to outputFile;
send "deleteYourself" to outputFile;
return (0);
}
WSDLtoOIL2:_outputPortWithBinding(array portElem)
{
assoc portInfo, locInfo;
array locElem;
set lines;
any messLines;
portInfo = call "_convertToAssoc"(portElem);
for locElem in portElem[0] do break;
locInfo = call "_convertToAssoc"(locElem);
display("outputPortWithBinding portInfo=",portInfo,"\n");
lines += "class ";
lines += "Experimental . ";
lines += className;
lines += " {\n";
lines += "/*!\n";
lines += "Automatically generated by class=WSDLtoOIL2.\n";
lines += "!*/\n";
lines += "\tstring\ttargetURL;\n";
lines += "} inherits from SOAPservice, XMLsupport;\n\n";
lines += className;
lines += ":create()\n{\n";
lines += "\ttargetURL = \"";
lines += locInfo["location"];
lines += "\";\n";
lines += "}\n\n";
messLines = call "_outputBindingsToPort"(portInfo);
lines |= messLines;
return (lines);
}
WSDLtoOIL2:_outputBindingsToPort(assoc portInfo)
{
set lines;
string bindingType, bindingName;
any resultLines;
int i;
display("outputPort\n");
bindingType = portInfo["binding"];
if (indexExists(bindingDefs, bindingType) != 0) {
bindingName = bindingType;
} else {
i = findSubstring(bindingType, ":");
i += 1;
bindingName = midstr(bindingType, i, length(bindingType) - i);
}
if (indexExists(bindingDefs, bindingName) == 0) {
display("No such binding for ", portInfo["name"], " binding=",
bindingName, "\n");
return ("");
}
display("outputBindingsToPort bindingName=", bindingName,"\n");
resultLines = call "_outputBinding"(portInfo, bindingDefs[bindingName]);
return (resultLines);
}
WSDLtoOIL2:_outputBinding(assoc portInfo, array bindingInfo)
{
array elem;
set resultLines;
any methodLines;
display("outputBinding, bindingInfo=",bindingInfo);
for elem in bindingInfo[0] do {
if (elem[1] == "soap:binding") {
}
if (elem[1] == "operation") {
methodLines = call "_outputOperation"(portInfo, bindingInfo, elem);
resultLines |= methodLines;
}
}
return (resultLines);
}
WSDLtoOIL2:_outputOperation(assoc portInfo, array bindingInfo, array operationInfo)
{
string opName, portTypeName;
set lines;
assoc attr;
any methodLines;
array opElem, portTypeElem;
int hadFault;
display("outputOperation portInfo=",portInfo,"\nopInfo=",operationInfo);
portTypeName = portInfo["name"];
if (indexExists(portTypeDefs, portTypeName) == 0) {
display("No portType for ",portTypeName, "\n");
return ("");
}
portTypeElem = portTypeDefs[portTypeName];
display("portTypeElem=", portTypeElem);
for opElem in portTypeElem[0] do {
methodLines = call "_outputOperationCode"(portInfo, bindingInfo, operationInfo, opElem);
lines |= methodLines;
}
return (lines);
}
WSDLtoOIL2:_outputOperationCode(assoc portInfo, array bindingInfo, array operationInfo, array messageElem)
{
string opName, portTypeName, messName;
string encodeName, decodeName;
set lines;
assoc attr, attr2, portOperations;
any methodData, argLine;
array opElem, portOpElem;
int hadFault;
// operationInfo determines method to output
attr = call "_convertToAssoc"(operationInfo);
opName = attr["name"];
attr = call "_convertToAssoc"(messageElem);
messName = attr["name"];
if (opName != messName) {
display("opName-", opName, " vs. messName-", messName, "\n");
return (""); // skip
}
display("outputOperationCode opName=",opName,"\n");
display("operationInfo=", operationInfo);
display("messageElem=", messageElem);
for opElem in messageElem[0] do {
display("opElem[1]=", opElem[1], "\n");
if (opElem[1] == "input") {
methodData = call "_outputEncodeMethod"(portInfo, bindingInfo, attr, opElem);
encodeName = methodData[1];
argLine = methodData[2];
lines |= methodData[0];
}
if (opElem[1] == "output") {
methodData = call "_outputDecodeMethod"(portInfo, bindingInfo, attr, opElem);
decodeName = methodData[1];
lines |= methodData[0];
}
if (opElem[1] == "fault") {
hadFault = 1;
methodData = call "_outputDecodeMethod"(portInfo, bindingInfo, attr, opElem);
lines |= methodData[0];
}
}
lines += className;
lines += ":";
lines += opName;
lines += "(";
// method args
lines |= argLine;
lines += ")\n{\n";
lines += "/*!\n";
lines += "Top-level RPC-style invocation.\n";
lines += "!*/\n";
lines += "\tstring\tpacket;\n";
lines += "\tint\trc;\n";
lines += "\tany\tresult, response;\n";
lines += "\n";
lines += "\tpacket = call \"_encode_";
lines += encodeName;
lines += "\"(arrayToSet(argv));\n";
lines += "\trc = call \"issueRequest\"(targetURL, packet);\n";
lines += "\tresponse = call \"receiveResponse\"();\n";
lines += "\tif (response == nil) return (nil);\n";
lines += "\tresult = call \"_decode_";
lines += decodeName;
lines += "\"(response);\n";
lines += "\treturn(result);\n";
lines += "}\n\n";
return (lines);
}
WSDLtoOIL2:_outputEncodeMethod(assoc portInfo, array bindingInfo, assoc opInfo,
array methodInfo)
{
string opName, messName, mName;
set lines, argLine;
assoc attr, partAttr, bindingAttr;
any methodData, bindingData;
array result, partInfo, messDef, bindingRec, opRec, mElem;
int i, count;
display("outputEncodeMethod methodInfo=",methodInfo);
opName = opInfo["name"];
display("top opName=",opName,"\n");
display("BINDING INFO=", bindingInfo);
attr = call "_convertToAssoc"(methodInfo);
messName = attr["message"];
if (indexExists(messageDefs, messName) == 0) {
i = findSubstring(messName, ":");
i += 1;
messName = midstr(messName, i, length(messName) - i);
if (indexExists(messageDefs, messName) == 0) {
display("No message def for ", messName, "\n");
return ("");
}
}
messDef = messageDefs[messName];
display("messageName=", messName, "\nmessDef=", messDef);
for bindingRec in bindingInfo[0] do {
display("bindingRec[1]=", bindingRec[1], "\n");
if (bindingRec[1] != "operation") continue;
bindingAttr = call "_convertToAssoc"(bindingRec);
display("binding name=", bindingAttr["name"], " vs. opName=", opName, "\n");
if (bindingAttr["name"] != opName) continue;
for opRec in bindingRec[0] do {
display("OPREC=",opRec);
if (opRec[1] != methodInfo[1]) continue;
for bindingData in opRec[0] do break;
}
if (bindingData != nil) break;
}
display("BINDING DATA=", bindingData, "\n");
if (bindingData == nil) {
display("Cannot find binding data for ", attr["name"], "\n");
return ("");
}
bindingAttr = call "_convertToAssoc"(bindingData);
lines += className;
lines += ":_encode_";
lines += messName;
lines += "(";
count = 0;
for partInfo in messDef[0] do {
partAttr = call "_convertToAssoc"(partInfo);
if (count != 0) argLine += ", ";
argLine += call "_mapToOIL2type"(partAttr["type"]);
argLine += " ";
argLine += partAttr["name"];
argLine += "ARG"; // avoid collisions with keywords
count += 1;
}
lines |= argLine;
lines += ")\n{\n";
// method body
lines += "\tset\txmlLines;\n";
lines += "\tstring\tresult;\n";
lines += "\tany\tparamLine;\n";
lines += "\n";
lines += "\tparamLine = call \"getSOAPenvelopeHeader\"(";
lines += "\"";
lines += opName; // operation name == envelope body
lines += "\",\n\t\t";
lines += "\"";
lines += bindingAttr["namespace"];
lines += "\",\n\t\t";
lines += "\"";
lines += bindingAttr["encodingStyle"];
lines += "\");\n";
lines += "\txmlLines |= paramLine;\n";
// encode each argument...
for partInfo in messDef[0] do {
partAttr = call "_convertToAssoc"(partInfo);
mName = call "_getEncodeMethodName"(partAttr["type"]);
lines += "\tparamLine = call \"";
lines += mName;
lines += "\"(";
lines += partAttr["name"];
lines += "ARG"; // avoid collisions with keywords
lines += ", \"";
lines += partAttr["name"];
lines += "\", \"";
lines += partAttr["type"];
lines += "\");\n";
lines += "\txmlLines |= paramLine;\n";
}
lines += "\tparamLine = call \"getSOAPenvelopeClosing\"(";
lines += "\"";
lines += opName;
lines += "\");\n";
lines += "\txmlLines |= paramLine;\n";
lines += "\tresult = makeAsString(xmlLines);\n";
lines += "\treturn (result);\n";
lines += "}\n\n";
result[0] = lines;
result[1] = messName;
result[2] = argLine;
return (result);
}
WSDLtoOIL2:_outputDecodeMethod(assoc portInfo, assoc bindingInfo, assoc opInfo,
array methodInfo)
{
string opName, messName, assignment;
set lines;
assoc attr, partAttr;
any methodData;
array result, partInfo, messDef;
int i, count;
opName = opInfo["name"];
display("top opName=",opName,"\n");
attr = call "_convertToAssoc"(methodInfo);
messName = attr["message"];
if (indexExists(messageDefs, messName) == 0) {
i = findSubstring(messName, ":");
i += 1;
messName = midstr(messName, i, length(messName) - i);
if (indexExists(messageDefs, messName) == 0) {
display("No message def for ", messName, "\n");
return ("");
}
}
messDef = messageDefs[messName];
lines += className;
lines += ":_decode_";
lines += messName;
lines += "(array xmlParse)\n";
lines += "{\n";
lines += "\tassoc\tresult;\n";
lines += "\tany\telem;\n";
lines += "\n";
// method body
lines += "\tfor elem in xmlParse[0] do {\n";
for partInfo in messDef[0] do {
if (partInfo[1] == "xsd:all") {
methodData = call "_outputConversionFromXML"(partInfo, "allElem = ");
lines |= methodData;
lines += "\treturn (allElem);\n";
lines += "\t\t}\n";
lines += "}\n";
return (lines);
}
partAttr = call "_convertToAssoc"(partInfo);
lines += "\t\tif (elem[1] == \"";
lines += partAttr["name"];
lines += "\") {\n";
assignment = makeAsString("\t\t\tresult[\"", partAttr["name"], "\"] = ");
methodData = call "_outputConversionFromXML"(partInfo, assignment);
lines |= methodData;
lines += "\t\t}\n";
}
lines += "\t}\n";
lines += "\treturn (result);\n";
lines += "}\n\n";
result[0] = lines;
result[1] = messName;
return (result);
}
WSDLtoOIL2:_outputConversionFromXML(array partInfo, string finalAssignment, optional array topLevel, optional string elemNameArg)
{
array subElem;
assoc partAttr, attr;
set lines;
string typeName, subAssign, elemName;
int i, isArray;
any lineData;
if (length(elemNameArg) > 0) {
elemName = elemNameArg;
} else {
elemName = "elem";
}
if (partInfo[1] == "xsd:complexContent") {
isArray = call "_isArray"(partInfo);
lines += "// xsd:complexContent ";
lines += thisMethod;
lines += makeAsString(" array=",isArray);
lines += "\n";
if (isArray != 0) {
subAssign = "\t\t\tresultArray[count] = ";
} else {
subAssign = finalAssignment;
}
for subElem in partInfo[0] do {
lineData = call "_outputConversionFromXML"(subElem, subAssign, partInfo, "elem");
lines |= lineData;
if (isArray != 0) {
lines += "\t\tcount += 1;\n";
} else {
lines += "\t\tbreak;\n";
}
break;
}
return (lines);
}
partAttr = call "_convertToAssoc"(partInfo);
if (partInfo[1] == "xsd:restriction") {
typeName = partAttr["base"];
for subElem in partInfo[0] do {
subAssign = "resultArray[count] = ";
lineData = call "_outputConversionFromXML"(subElem, finalAssignment, partInfo, elemName);
lines |= lineData;
break;
}
return (lines);
}
if (partInfo[1] == "xsd:all") {
lines += "// xsd:all\n";
lines += "\tfor subElem in elem[0] do {\n";
lines += "\t\tattr = call \"_convertToAssoc\"(subElem);\n";
for subElem in partInfo[0] do {
attr = call "_convertToAssoc"(subElem);
subAssign = makeAsString("\t\t\tresult[\"", attr["name"], "\"] = ");
lines += "\t\tattr = call \"_convertToAssoc\"(elem);\n";
lines += "\t\tif (attr[\"name\"] == \"";
lines += attr["name"];
lines += "\") {\n";
lineData = call "_outputConversionFromXML"(subElem, subAssign, elemName);
lines |= lineData;
lines += "\t\t}\n";
}
lines += "\t}\n";
lines += finalAssignment;
lines += "allAssoc;\n";
return (lines);
}
display("Output FromXML partInfo=", partInfo, " partAttr=", partAttr);
if (partInfo[1] == "xsd:attribute") {
attr = call "_convertToAssoc"(partInfo);
if (indexExists(attr, "wsdl:arrayType") != 0) typeName = attr["wsdl:arrayType"];
} else {
if (indexExists(partAttr, "type") != 0) typeName = partAttr["type"];
else if (indexExists(partAttr, "type") != 0) typeName = partAttr["type"];
}
if (length(typeName) == 0) {
display("NEED TO SUPPORT: ", partInfo[1], "\n");
return ("");
}
if ((typeName == "xsd:int") || (typeName == "xsd:unsignedInt")
|| (typeName == "xsd:short") || (typeName == "xsd:unsignedShort")) {
lines += finalAssignment;
lines += "stringToNumber(elem[2], int);\n";
return (lines);
}
if ((typeName == "xsd:long") || (typeName == "xsd:unsignedLong")) {
lines += finalAssignment;
lines += "stringToNumber(elem[2], int64);\n";
return (lines);
}
if (typeName == "xsd:boolean") {
lines += "\tif ((elem[2] == 0) || (elem[2] == \"false\")) ";
lines += finalAssignment;
lines += "0;\n\telse ";
lines += finalAssignment;
lines += "1;\n";
return (lines);
}
if (typeName == "xsd:float") {
lines += finalAssignment;
lines += "stringToNumber(elem[2], float);\n";
return (lines);
}
if (typeName == "xsd:double") {
lines += finalAssignment;
lines += "stringToNumber(elem[2], double);\n";
return (lines);
}
if (typeName == "xsd:decimal") {
lines += finalAssignment;
lines += "stringToNumber(elem[2], fixed);\n";
return (lines);
}
if ((typeName == "xsd:byte") || (typeName == "xsd:unsignedByte")) {
lines += finalAssignment;
lines += "midchar(elem[2], 0);\n";
return (lines);
}
if (typeName == "xsd:base64Binary") {
lines += finalAssignment;
lines += "base64ToASCII(elem[2]);\n";
return (lines);
}
if (typeName == "xsd:hexBinary") {
lines += finalAssignment;
lines += "makeAsHexString(elem[2]);\n";
return (lines);
}
if ((typeName == "xsd:string") || (typeName == "normalizedString")
|| (typeName == "xsd:token")) {
lines += finalAssignment;
lines += "elem[2];\n";
return (lines);
}
if (indexExists(typeDefs, typeName) == 0) {
i = findSubstring(typeName, ":");
if (i != -1) {
i += 1;
typeName = midstr(typeName, i, length(typeName) - i);
}
i = findSubstring(typeName, "[]");
if (i != -1) {
typeName = midstr(typeName, 0, i);
}
}
display("typeName=",typeName,"\n");
display("typeDefs=",typeDefs);
if (indexExists(typeDefs, typeName) != 0) {
//lines += makeAsString("// COMPLEX ", typeName, "\n");
lines += finalAssignment;
lines += "call \"_decodeComplex_";
lines += typeName;
lines += makeAsString("\"(",elemName,");\n");
return (lines);
}
lines += makeAsString("// UNKNOWN ", partAttr["type"], "\n");
// default, copy as-is
lines += finalAssignment;
lines += "elem[2];\n";
return (lines);
}
WSDLtoOIL2:_noteTypes(array elem)
{
array topElem, typeElem;
assoc info, attr;
//display("Note types=", elem);
for topElem in elem[0] do {
info = call "_convertToAssoc"(topElem);
for typeElem in topElem[0] do {
attr = call "_convertToAssoc"(typeElem);
typeDefs[attr["name"]] = typeElem;
}
}
return (0);
}
WSDLtoOIL2:_noteBinding(array elem)
{
assoc attr;
attr = call "_convertToAssoc"(elem);
bindingDefs[attr["name"]] = elem;
return (0);
}
WSDLtoOIL2:_noteMessage(array elem)
{
assoc attr;
attr = call "_convertToAssoc"(elem);
messageDefs[attr["name"]] = elem;
return (0);
}
WSDLtoOIL2:_notePortType(array elem)
{
assoc attr;
attr = call "_convertToAssoc"(elem);
portTypeDefs[attr["name"]] = elem;
return (0);
}
WSDLtoOIL2:_outputComplexDecodeMethod(array typeElem)
{
set lines;
assoc attr, attr2;
string typeName, assignment;
array subElem, elem2;
any methodData;
int outputConvert, isArray;
attr = call "_convertToAssoc"(typeElem);
typeName = attr["name"];
lines += className;
lines += ":_decodeComplex_";
lines += typeName;
lines += "(array xmlParse) // ";
lines += thisMethod;
lines += "\n{\n";
lines += "\tassoc\tresult, attr;\n";
lines += "\tarray\tresultArray;\n";
lines += "\tint\tcount;\n";
lines += "\tany\telem, subElem, complexResult;\n";
lines += "\n";
//lines += makeAsString("display(\"",typeName," argv=\",argv);\n");
lines += "\tfor elem in xmlParse[0] do {\n";
//lines += makeAsString("// ", typeElem[1], " ", typeElem[4], "\n");
for subElem in typeElem[0] do {
//display("SUB ELEM=", subElem);
attr = call "_convertToAssoc"(subElem);
if (subElem[1] == "xsd:all") {
for elem2 in subElem[0] do {
//display("ELEM2=", subElem);
attr2 = call "_convertToAssoc"(elem2);
assignment = makeAsString("\t\t\tresult[\"", attr2["name"], "\"] = ");
lines += "\t\tif (elem[1] == \"";
lines += attr2["name"];
lines += "\") {\n";
methodData = call "_outputConversionFromXML"(elem2, assignment);
lines |= methodData;
lines += "\t\t}\n";
}
break;
}
if (subElem[1] = "xsd:complexContent") {
assignment = "\t\t\tcomplexResult = ";
methodData = call "_outputConversionFromXML"(subElem, assignment);
lines |= methodData;
isArray = call "_isArray"(subElem);
if (isArray == 0) {
lines += "\t\t\treturn (complexResult); // done\n";
}
break;
}
assignment = makeAsString("\tresult[\"", attr["name"], "\"] = ");
if (outputConvert == 0) { // once only
lines += "\t\tattr = call \"_convertToAssoc\"(elem);\n";
lines += "display(attr);\n";
outputConvert = 1;
}
lines += "\t\tif (attr[\"name\"] == \"";
lines += attr["name"];
lines += "\") {\n";
methodData = call "_outputConversionFromXML"(subElem, assignment);
lines |= methodData;
lines += "\t\t}\n";
}
lines += "\t}\n";
if (isArray == 1) {
lines += "\treturn (resultArray);\n";
} else {
lines += "\treturn (result);\n";
}
lines += "}\n\n";
return (lines);
}