Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <cffunction name="ConvertXmlToStruct" access="public" returntype="struct" output="false"
- hint="Parse raw XML response body into ColdFusion structs and arrays and return it.">
- <cfargument name="xmlNode" type="string" required="true" />
- <cfargument name="str" type="struct" required="true" />
- <!---Setup local variables for recurse: --->
- <cfset var i = 0 />
- <cfset var axml = arguments.xmlNode />
- <cfset var astr = arguments.str />
- <cfset var n = "" />
- <cfset var tmpContainer = "" />
- <cfset axml = XmlSearch(XmlParse(arguments.xmlNode),"/node()")>
- <cfset axml = axml[1] />
- <!--- For each children of context node: --->
- <cfloop from="1" to="#arrayLen(axml.XmlChildren)#" index="i">
- <!--- Read XML node name without namespace: --->
- <cfset n = replace(axml.XmlChildren[i].XmlName, axml.XmlChildren[i].XmlNsPrefix&":", "") />
- <!--- If key with that name exists within output struct ... --->
- <cfif structKeyExists(astr, n)>
- <!--- ... and is not an array... --->
- <cfif not isArray(astr[n])>
- <!--- ... get this item into temp variable, ... --->
- <cfset tmpContainer = astr[n] />
- <!--- ... setup array for this item beacuse we have multiple items with same name, ... --->
- <cfset astr[n] = arrayNew(1) />
- <!--- ... and reassing temp item as a first element of new array: --->
- <cfset astr[n][1] = tmpContainer />
- <cfelse>
- <!--- Item is already an array: --->
- </cfif>
- <cfif arrayLen(axml.XmlChildren[i].XmlChildren) gt 0>
- <!--- recurse call: get complex item: --->
- <cfset astr[n][arrayLen(astr[n])+1] = ConvertXmlToStruct(axml.XmlChildren[i], structNew()) />
- <cfelse>
- <!--- else: assign node value as last element of array: --->
- <cfset astr[n][arrayLen(astr[n])+1] = axml.XmlChildren[i].XmlText />
- </cfif>
- <cfelse>
- <!---
- This is not a struct. This may be first tag with some name.
- This may also be one and only tag with this name.
- --->
- <!---
- If context child node has child nodes (which means it will be complex type): --->
- <cfif arrayLen(axml.XmlChildren[i].XmlChildren) gt 0>
- <!--- recurse call: get complex item: --->
- <cfset astr[n] = ConvertXmlToStruct(axml.XmlChildren[i], structNew()) />
- <cfelse>
- <cfif IsStruct(aXml.XmlAttributes) AND StructCount(aXml.XmlAttributes)>
- <cfset at_list = StructKeyList(aXml.XmlAttributes)>
- <cfloop from="1" to="#listLen(at_list)#" index="atr">
- <cfif ListgetAt(at_list,atr) CONTAINS "xmlns:">
- <!--- remove any namespace attributes--->
- <cfset Structdelete(axml.XmlAttributes, listgetAt(at_list,atr))>
- </cfif>
- </cfloop>
- <!--- if there are any atributes left, append them to the response--->
- <cfif StructCount(axml.XmlAttributes) GT 0>
- <cfset astr['_attributes'] = axml.XmlAttributes />
- </cfif>
- </cfif>
- <!--- else: assign node value as last element of array: --->
- <!--- if there are any attributes on this element--->
- <cfif IsStruct(aXml.XmlChildren[i].XmlAttributes) AND StructCount(aXml.XmlChildren[i].XmlAttributes) GT 0>
- <!--- assign the text --->
- <cfset astr[n] = axml.XmlChildren[i].XmlText />
- <!--- check if there are no attributes with xmlns: , we dont want namespaces to be in the response--->
- <cfset attrib_list = StructKeylist(axml.XmlChildren[i].XmlAttributes) />
- <cfloop from="1" to="#listLen(attrib_list)#" index="attrib">
- <cfif ListgetAt(attrib_list,attrib) CONTAINS "xmlns:">
- <!--- remove any namespace attributes--->
- <cfset Structdelete(axml.XmlChildren[i].XmlAttributes, listgetAt(attrib_list,attrib))>
- </cfif>
- </cfloop>
- <!--- if there are any atributes left, append them to the response--->
- <cfif StructCount(axml.XmlChildren[i].XmlAttributes) GT 0>
- <cfset astr[n&'_attributes'] = axml.XmlChildren[i].XmlAttributes />
- </cfif>
- <cfelse>
- <cfset astr[n] = axml.XmlChildren[i].XmlText />
- </cfif>
- </cfif>
- </cfif>
- </cfloop>
- <!--- return struct: --->
- <cfreturn astr />
- </cffunction>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement