Coldfusion XML to Struct

On November 5, 2007, in ColdFusion, by Anuj Gakhar

XML parsing in Coldfusion has improved a lot in the last few versions but converting a complex XML object to a Coldfusion structure is still a struggle I beleive. There are a few custom tags out there for doing this but the ones that I have used or know are all only for simple structures, not nested or subnested structures. So I use this little function I and one of my other friends worked on and it works like a charm.

Update (27/12/2008) : The new code has been upload on riaforge and the usage is now very simple . It now takes the XML file and converts to Struct without doing all the Xpath’s before the function call. Here is a sample usage.

<cffile action="read" file="#ExpandPath('books.xml')#" variable="myBooks">
<cfdump var = "#ConvertXmlToStruct(ToString(myBooks), structnew())#">

The new code is here as well – Xml2Struct CFC

Anything below is now outdated :-

Update : Project can now be downloaded from here

A sample usage of the fucntion is below :-

Read the XML file into a Coldfusion variable, this can be a from a file locally or via a CFHTTP call or a webservice call.

<cffile action="read" file="#ExpandPath('books.xml')#" variable="myBooks">
<cfset myXml = XmlParse(myBooks) />
You need to know the root element of the XML document and pass that to the function.
<cfset xmlBody= xmlSearch(myXml,"//catalog") />

Then call the function to convert it to a Structure.

<cfdump var = "#ConvertXmlToStruct(responseBody[1], structnew())#">

The function itself can be found here.

The only problem that I notice about this is if the root element has any default namespaces (“xmlns=’blabla’) , the XmlSearch doesnt recognise it. Apart from that, it works like a charm.

The XML file used in this sample can be found here books sample xml file .

Screen Dump of OutputHere is the output of the code.

Tagged with:  

81 Responses to Coldfusion XML to Struct

  1. Hello Anuj,

    Thanks for the awesome .cfc!

    I have a quick question. Suppose you have an array inside a struct which only has one element. By default it appears that your function will turn that array into a struct within a struct. Is it possible to force it to make an array within a struct, even though that array has only one element?

    Thanks!

  2. Anuj Gakhar says:

    @Brad, I will try and re-visit the CFC today/tomorrow. I think there are a few things I can change around and optimize. I will let you know.

  3. Thanks Anuj! I’m not smart enough to figure it out, but I was thinking that somehow how you could program it so that if you use a preset node name, that it would automatically make it an array. For example,

    this will be an array

    So, if someone uses “arelement” (or something similar), then the function would process that as an array.

    This is just a thought.

    Thanks again!!

    brad

  4. oops, looked liked it deleted the code; bout

    -books-
    -arelement-This is an array-/arelement-
    -/books

    (replace – with )

  5. James Basco says:

    Thanks for the great code!

    Works perfect for a quick way to consume an XML webservice then turn around and return a JSON object.

  6. Dave says:

    Hi Anuj,

    Brad posted this awhile back:

    “Hello Anuj,

    Thanks for the awesome .cfc!

    I have a quick question. Suppose you have an array inside a struct which only has one element. By default it appears that your function will turn that array into a struct within a struct. Is it possible to force it to make an array within a struct, even though that array has only one element?”

    I have run into the same need. The inconsistency caused by it creating an array within a stuct followed by a struct within a struct makes it hard to use the output. Any chance you can modify this to always create an array within a struct even though the stuct may only have 1 element?

  7. Anuj Gakhar says:

    Hi Dave, That should be easy to change. I will have a look and get back. Give me a couple of days though.

  8. Dave says:

    Anuj,

    Thanks, I appreciate it. Your code will solve a problem on a project I’m working on. Really appreciate your sharing your work.

  9. Dave says:

    Hi Anuj,

    I hate to ask because I know that you’re doing me a favor, but is there any chance you might be able to make the modification to the code today? If it doesn’t look like you’ll be able to get to it, I’ll have to figure something else out. My project needs to be done by the morning. Just thought I would ask to see if you might have time.

    Thanks!

    Dave

    • Anuj Gakhar says:

      Hi Dave, Sorry I have just got back online. I am afraid I wont have any time before the weekend. But it should be a pretty simple change to do and you can give it a shot and try doing it yourself meanwhile. Otherwise I will have a look during the weekend sometime.

  10. Dave says:

    Hi Anuj,

    I spent the entire day trying to make the change. I put displays in all over the place and still can’t quite follow the logic.

    If you’re able to make the change this weekend, I’d greatly appreciate your help.

  11. Dave says:

    Hi Anuj,

    Hope your weekend is going well. Still look like you might have time to work on this today?

  12. Fred Homes says:

    I love how coldfusion is able to work with xml. That makes it a lot easier for programmers to organize the system contents and much easier for editing them. I find that the best use for xml is for detecting an error, or an unwanted ‘member’ inside a long code. I believe this is how OOP should be.

    Fred Homes
    architects Tucson

  13. Tyler says:

    Coldfusion can actually do a whole lot more but we need the time and knowledge to explore more. Thanks for sharing Anuj.

  14. Jack says:

    I’ve spent ages looking for help with a function for subnested structures; landing here was worth the effort. Job done.

  15. Anthony says:

    Nice code, however, it bombs if the first item in the xml doc is not a node(). For example, if the first item is a comment, XMLSpy is bad about that.

  16. Joe says:

    Do you happen to have a function that takes this converted struct and transforms directly back to the original xml?

  17. Michael says:

    Great Anuj! Absolutely useful to me this time. So glad I bumped into this blog. Two thumbs up!!! I am in great owe of you. Thanks. More power!

  18. Clarence Liu says:

    This is throwing away the xmlAttributes if there are xmlChildren, if you need that data I added a line here, ~line 54:

    • Clarence Liu says:

      Ah nvm won’t let me post code here =/

    • Clarence Liu says:

      I’ll just describe it then,

      There are two comments: “recurse call: get complex item:”, line 39 and 53, after the code that runs on the next line, you have access to the XmlAttributes through “axml.XmlChildren[i].XmlAttributes”, just add it however you want to the same struct just referenced

  19. webhelio says:

    Can’t get the XML attributes to show up…. Useless unless I can access the attributes.

  20. Clarence Liu says:

    I was having performance issues, since we still use CF for some legacy stuff I’ll post this quick fix, the main issue is ”
    ” should not be called for every recursion! This is really slow, it only has to be called once ever. So just make a copy of the function and directly assign axml to be arguments.xmlNode – rewrite the recursion call to itself not the original function. Call the original function first, but call your new copied function thereafter, testing gives me about 10x performance increase.

    • Clarence Liu says:

      Oops no code, between the double quotes I meant: “axml = XmlSearch(XmlParse(arguments.xmlNode),”/node()”)” and “axml = axml[1]” is the killer, this only ever needs to be called once at the start. Actually dumb of me to say copy the method, just make a small method to call first that does the ‘XmlSearch(XmlParse(arguments.xmlNode),”/node()”)’ and pass the result in. Then you only need one convertXmlToStruct method.

  21. spidre409 says:

    Just gotta give you a HUGE thankyou for this cfc. It makes reading complex SOAP Responses so easy to do!

Leave a Reply

© 2011 Anuj Gakhar
%d bloggers like this: