It is not that often to work with XML nowadays (at least – for our clients), but we have such a task from time to time. Today, I was asked to parse some text taken from the database. This text is in fact a piece of XML:
<application:layout> <text:color fg="880022" bg="FFFFFF" /> </application:layout>
Unfortunately, when trying to parse like this:
<cfset result = xmlParse(textToParse)>
I got the following error:
The prefix "application" for element "application:layout" is not bound.
The source of this issue is the fact that the XML parser is looking at the “application:layout” and takes “application” as the namespace in which “layout” is located. The same issue will occur for “text:color” – it will be treated as the “text” namespace with the “color” element.
Possible solutions – the ugly one…
If you are not concerned about the actual values of these elements, you can simply replace “application:layout” with “appliation_layout” and “text:color” with “text_color”. This time the parse will work:
Of course, the element names are now altered, so you have to adjust the rest of the code accordingly.
…and the more elegant one
If you have to keep the values, you should use the following: pack the content you have ot parse into the <document> with proper “xmlns” definitions. This will add new namespaces. In our case, we have to add two namespaces: one for application, one for text:
<cfset textToParse = '<application:layout><text:color fg="880022" bg="FFFFFF" /></application:layout>'> <cfset documentStart = '<document xmlns:application="http://www.w3.org/2001/XMLSchema-instance" xmlns:text="http://www.w3.org/2001/XMLSchema-instance" >' > <cfset documentEnd = '</document>' > <cfset result = xmlParse(documentStart & textToParse & documentEnd)> <cfdump var="#result#">
Now, our variable is “wrapped” in the document that got proper namespaces definitions. The code above produces the following output:
If you have to handle only the original piece of XML code, you can use:
Which will produce the following output: