Building A ColdFusion XML Document From Scratch
Posted May 14, 2007 at 2:27 PM
This is a basic exploration of the ColdFusion XML functions and methodologies that can be used to construct a ColdFusion XML document object model from scratch. I am doing this, not because it is ground breaking, but simply because I have never done it before and it really is something that I should know how to do. Here is my exploratory code - it uses XmlNew() to generate a new XML DOM (document object model) and then other methods and properties to flesh it out:
Launch code in new window » Download code as text file »
- <!--- Create a new XML girl object. --->
- <cfset xmlGirl = XmlNew() />
-
- <!---
- Create a root xml node under which every
- other XML node for this document will reside.
- Notice that we have to create this new root
- node in the context of our existing XML document
- so that the document owner is properly set.
- --->
- <cfset xmlRoot = XmlElemNew( xmlGirl, "", "girl" ) />
-
- <!---
- Our new xml node is now owned by the girl
- document, but it is not yet part of the DOM. We
- need to explicitly set the root XML node of the
- girl to point to our newly created XML node.
- --->
- <cfset xmlGirl.XmlRoot = xmlRoot />
-
-
- <!---
- Create a node to hold information about her
- personality (ex. smart, funny, kind). This
- will be a child of the root node.
- --->
- <cfset xmlPersonality = XmlElemNew( xmlGirl, "", "personality" ) />
-
- <!--- Append the personality to the root. --->
- <cfset ArrayAppend(
- xmlRoot.XmlChildren,
- xmlPersonality
- ) />
-
-
- <!---
- Create a node to hold information about her body
- (ex. measurements, color, etc). This will be a
- child of the root node.
- --->
- <cfset xmlBody = XmlElemNew( xmlGirl, "", "body" ) />
-
- <!--- Append the body to the root. --->
- <cfset ArrayAppend(
- xmlRoot.XmlChildren,
- xmlBody
- ) />
-
-
- <!---
- Now, that we have the basic containers down for
- this XML document, we are going to flesh out the
- sub structures.
- --->
-
-
- <!---
- First, we are going to create some properties for
- the personality. These are going to consist of
- attribute-driven data values.
-
- NOTE: We cannot just use the reference to xmlPersonality
- that we generated above. This does not actually point
- to the XML node that we need to update.
- --->
- <cfset xmlRoot.Personality.XmlAttributes.Fun = true />
- <cfset xmlRoot.Personality.XmlAttributes.Happy = true />
- <cfset xmlRoot.Personality.XmlAttributes.Nice = true />
- <cfset xmlRoot.Personality.XmlAttributes.Generous = false />
- <cfset xmlRoot.Personality.XmlAttributes.Evil = false />
-
-
- <!---
- Next, we are going to create some properties for the
- body. These are going to consist of attribute-
- driven data values.
-
- NOTE: We cannot just use the reference to xmlBody
- that we generated above. This does not actually point
- to the XML node that we need to update.
- --->
- <cfset xmlRoot.Body.XmlAttributes.Hair = "Blonde" />
- <cfset xmlRoot.Body.XmlAttributes.Eyes = "Brown" />
- <cfset xmlRoot.Body.XmlAttributes.Bust = 36 />
- <cfset xmlRoot.Body.XmlAttributes.Waist = 24 />
- <cfset xmlRoot.Body.XmlAttributes.Hips = 36 />
-
-
- <!--- Dump out the resultant XML document object. --->
- <cfdump
- var="#xmlGirl#"
- label="xmlGirl XML DOM"
- />
When all is said and done, here is a CFDump of the resultant ColdFusion XML document:
| | | | ||
| | ![]() | | ||
| | | |
Then, if we call ToString() on the resultand DOM, we get:
Launch code in new window » Download code as text file »
- <?xml version="1.0" encoding="UTF-8"?>
- <girl xmlns="">
-
- <personality
- EVIL="false"
- FUN="true"
- GENEROUS="false"
- HAPPY="true"
- NICE="true"
- xmlns=""
- />
-
- <body
- BUST="36"
- EYES="Brown"
- HAIR="Blonde"
- HIPS="36"
- WAIST="24"
- xmlns=""
- />
-
- </girl>
That was relatively easy to work with. That'll do ColdFusion... that'll do.
Download Code Snippet ZIP File
Post Comment | Ask Ben | Other Searches | Print Page
Newer Post
ColdFusion XML Nodes Are Passed By Value, Not By Reference
Older Post
WRONG_DOCUMENT_ERR: A Node Is Used In A Different Document Than The One That Created It
Reader Comments
Here's an alternate method that I use a lot. I prefer this way because it helps me if I can see the tag structure.
-------------------------------------------------------------------------------
<cfsavecontent variable="xsl">
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
</cfsavecontent>
<cfxml variable="xmlGirl>
<cfoutput>
<?xml version="1.0" encoding="UTF-8"?>
<girl>
<personality>
<evil>true</evil>
<fun>true</fun>
<generous>false</generous>
<happy>true</happy>
<nice>true</nice>
</personality>
<body>
<eyes>brown</eyes>
<hair>blonde</hair>
<hips>36</hips>
<waist>24</waist>
<bust>36</bust>
</body>
</girl>
</cfoutput>
</cfxml>
<cfcontent variable="#ToBinary(ToBase64(XMLTransform(xmlGirl,xsl)))#" type="text/xml" />
Is there a reason why you are assigning things to a variable, and then putting them into your xml document?
Why do
1) xmlRoot = XmlElemNew( xmlGirl, "", "girl" )
2) xmlGirl.XmlRoot = xmlRoot
When you could just do
1) xmlGirl.XmlRoot = XmlElemNew( xmlGirl, "", "girl" )
??
@Matt,
That's cool looking. I really do need to learn more about XSLT. My only issue (other than not know XSLT) was that I was trying to create the XML document without using tags... I agree that tags are WAYYYYY better as you can easily see the structure - but I have done that before. I have never used XmlNew() before this.
@Rich,
I like to break things up into steps because I find it is easier to follow the individual steps. You might lose some sense of the "overall" scope of the problem, but I like to attack the problems individually. For instance, in my example, I am performing 1) Node creation, and 2) Node setting in two steps and explaining them individually... you are doing both of those in a single line of code. It's just a personal preference, but I feel like breaking them apart is slightly better for teaching because it's less you need to understand per code-line.
Sorry if that didn't make any sense.
I can understand that (for teaching purposes). When actually writing something to use this, it seems easier to me to just do it in one line and not have to worry about value/reference issues and remembering to assign things back to your xml object in a second line.
One other note (maybe this is more style based as well)...
Instead of:
xmlRoot.Personality.XmlAttributes.Fun = true
I tend to use:
StructInsert(xmlRoot.PersonalityXmlAttributes, "Fun", true);
This essentially does the same thing, but after spending some time troubling to troubleshoot some weird errors (I have a process that creates a custom xml "file" in memory, then uses that xml transformed with xsl to write CF files), I started doing the second instead of the first to be able to control the case of the xml attributes. Not sure why, but no matter how you type the attribute name in the first example, it always ended up with each letter capitalized (which broke my xsl, which was looking for a specific case of the attribute apparently??). The second example allowed me to control exactly how the attribute name was written out.
Hope that helps somebody else.
@Rich,
That is good to know about the case of the tag name when using StructInsert(). I did notice that they were call coming out upper cased in my CFDumps. I figured since CF isn't case sensitive it doesn't matter... but I guess when dealing with XML, more things are case sensitive, including this XSLT that you use.
That is a really good tip to know. Thanks.
Even though I love CF, I have found a really nice Java Library called JDOM to do these things, which, if you put the jar files in your server you can do things in a much nicer (and faster!) way.
check it out!
@Mark,
That's funny you mention is because my recent XML exploration was triggered by someone asking me about JDOM. I don't know anything about it, but it made me realize that I haven't done too much with XML either. I hear good stuff about this JDOM. Thanks for the link. I will check it out.
A while ago I had to create an xml document using the described method. That worked very well. The only problem I had was adding a stylesheet to the xml document.
I ended up replacing the first node name, with my stylesheet and adding the first node name again.
Something like:
<cfset xmldoc = replaceNocase(xmldoc, '<rootnode>', '<?xml-stylesheet type="text/css" href="/default.css" ?>
<rootnode>, 'ONE')>
I'm sure there's a better method....... i hope?
@Ron,
I am not sure how you get/set the style sheet node with the API. I am trying to look into it, but not coming up with much.




