0

XML StAX Processing with Coldfusion

XML, Coldfusion

Several problems with Coldfusion XML processing and solution set:

  1. Slow: due to DOM processor (Xerces)
  2. Inconsistent Round-Tripping (i.e. serialization / deserialization) :
    1. (un-) escaping characters
    2. non-printable characters
    3. missing / multiple XML declaration(s)
    4. character set problems
    5. et al.
  3. Kludgy Tree API yes you can use structure and array functions, just don't like it.

Note, don't see this as a flame on Adobe/Macromedia. The Coldfusion XML implementation uses best available technology at the time and APIs that fit in with the language paradigm. Just have better options now.

Slow Solution

Woodstox: Jim Collins wrote a CFDJ article about using a StAX XML processor with Coldfusion. Unfortunately, as near as I can tell, his open source project to integrate Coldfusion with Woodstox was never released. Testing demonstrates a StAX processor, such as Woodstox, provides very efficient (read: fast) XML processing, and a more intuitive API, than a SAX processor. But still not intuitive enough for me. So enter...

Round-Tripping & API Solutions

XOM provides a very easy to use API that roundtrips XML like a champ. Correct I/O is XOM's middle name. But it doesn't integrate natively with a StAX processor unless you use...

NUX is like a Swiss Army knife for XML. But the purpose of this entry just know it's the glue between XOM and Woodstox (note that NUX includes the XOM jar so you do not need to download it separately).

Code

Download the Woodstox and NUX jars and configure them in your Coldfusion classpath. The examples below build upon each other.

Setup

Creates a XOM Builder object backed by a StAX processor.

inputFactory = createObject("java", "com.ctc.wstx.stax.WstxInputFactory").init()
builder = createObject("java", "nux.xom.io.StaxUtil").createBuilder(local.joInputFactory, javacast("null", "")

XMLParse() Alternative

Returns a XOM Document object. Note: provide XMLString variable.

document = builder.create(XMLString)

XMLSearch() Alternative

Returns a XOM Nodes object (i.e. an iterator of Node objects). Note: provide XQueryString variable.

nodes = createObject("java", "nux.com.xquery.XQueryUtil").xquery(document, XQueryString)

loop from="0" to="#nodes.size() - 1#" index="idx"
element = nodes.get(javacast("int", idx))
attributeValue = element.getAttribute("attributeName").getValue()
attributeText = element.getValue
/loop

ToString() Alternative

Creates a string representation of the XML.

XMLString = document.toXML()

tags:
ColdFusion
Matt said:
 
Okay, so I have done what is above, but now when I dump the nodes variable I get some weird Java stuff. I get this back:

object of nu.xom.Nodes
Class Name    nu.xom.Nodes
Methods    
Method    Return Type
append(nu.xom.Node)    void
contains(nu.xom.Node)    boolean
get(int)    nu.xom.Node
insert(nu.xom.Node, int)    void
remove(int)    nu.xom.Node
size()    int



How would I go about displaying the content of the parsed Xml?
 
posted 293 days ago
Add Comment Reply to: this comment OR this thread
 
 
index = 0

cfloop condition="index LTE nodes.size()"

// usually instance of nu.xom.Element
// but see nu.xom.Node JavaDoc for detail
node = nodes.get(index)

index = index + 1

/cfloop
 
posted 292 days ago
Add Comment Reply to: this comment OR this thread
 
Matt said:
 
Thank you for your response and help!

I still cannot get it to work. Your above comment displays the name of the xml tag, but not the value inside of it. Here is my test xml data:



John
Smith
412-555-1212
johnsmith@email.com



Then I do this XQueryString:



Now, when I display it:

#nodes.get(0)#


But that gives me this value: [nu.xom.Element: lastName]


It gives me the name of the XML tag, but not the value inside the lastName tag. How can I get the value? I am so close!


The reason I need the Stax is because I am requesting huge XML data and processing normally withing CF8 takes FOREVER! And the bigger the data gets, the slower it is for Coldfusion.

I have heard that with this Stax processing, it is much much faster. So it's the only solution to my problem right now.


Thanks..

 
posted 290 days ago
Add Comment Reply to: this comment OR this thread
 
Matt said:
 
I noticed that test xml data / cf strings are not displaying above. Here is same comment with properly formatted HTML/Coldfusion:


Thank you for your response and help!

I still cannot get it to work. Your above comment displays the name of the xml tag, but not the value inside of it. Here is my test xml data:



<phonebook>
<contact category="friend">
<firstName>John</firstName>
<lastName>Smith</lastName>
<phone>412-555-1212</phone>
<email>johnsmith@email.com</email>
</contact>
</phonebook>



Then I do this XQueryString:

>cfset Nodes = createObject("java", "nux.xom.xquery.XQueryUtil").xquery(Document, "/phonebook/contact/lastName")>

Now, when I display it:

#nodes.get(0)#


But that gives me this value: [nu.xom.Element: lastName]


It gives me the name of the XML tag, but not the value inside the lastName tag. How can I get the value? I am so close!


The reason I need the Stax is because I am requesting huge XML data and processing normally withing CF8 takes FOREVER! And the bigger the data gets, the slower it is for Coldfusion.

I have heard that with this Stax processing, it is much much faster. So it's the only solution to my problem right now.


Thanks..
 
posted 290 days ago
Add Comment Reply to: this comment OR this thread
 
 
Look at the JavaDocs: http://www.xom.nu/apidocs/index.html.

For your example try:

#nodes.get(0).getValue()#
 
posted 290 days ago
Add Comment Reply to: this comment OR this thread
 
Matt said:
 
Works!

Thank you so much! I will now test this to see how much better it is than the Coldfusion xml parser.
 
posted 290 days ago
Add Comment Reply to: this comment OR this thread
 

Search