Solved

How to create ONE xml object and add elements to it?

Posted on 2004-10-02
10
259 Views
Last Modified: 2013-12-24
Hi,

I want to create one xml object, so users can add elements/data to it and have it appended as opposed to making a new file each time.

I was going to use <cffile> to write the new form entries to this existing xml file.

How can this be done?

Basically I want to add/append to the xml file each time a user submits entries from a form.

Any thoughts?

-ws
0
Comment
Question by:Westside2004
  • 4
  • 3
  • 2
  • +1
10 Comments
 
LVL 21

Expert Comment

by:pinaldave
ID: 12209940
you can do this...

http://livedocs.macromedia.com/coldfusion/6.1/htmldocs/funca124.htm#wp4279953

<cfset testVar = True>
<cfscript>
   MyDoc = XmlNew();
   MyDoc.xmlRoot = XmlElemNew(MyDoc,"MyRoot");
   if (testVar IS TRUE)
      MyDoc.MyRoot.XmlText = "The value of testVar is True.";
   else
      MyDoc.MyRoot.XmlText = "The value of testVar is False.";
   for (i = 1; i LTE 4; i = i + 1)
      {
      MyDoc.MyRoot.XmlChildren[i] = XmlElemNew(MyDoc,"childNode");
      MyDoc.MyRoot.XmlChildren[i].XmlText = "This is Child node " & i &".";
      }
</cfscript>
<cfdump var=#MyDoc#>

=========================================

http://livedocs.macromedia.com/coldfusion/6.1/htmldocs/funca122.htm#wp4319442

<cfset testVar = True>
<cfscript>
   MyDoc = XmlNew();
   MyDoc.xmlRoot = XmlElemNew(MyDoc,"MyRoot");
   if (testVar IS TRUE)
      MyDoc.MyRoot.XmlText = "The value of testVar is True.";
   else
      MyDoc.MyRoot.XmlText = "The value of testVar is False.";
   for (i = 1; i LTE 4; i = i + 1)
      {
      MyDoc.MyRoot.XmlChildren[i] = XmlElemNew(MyDoc,"childNode");
      MyDoc.MyRoot.XmlChildren[i].XmlText = "This is Child node " & i &".";
      }
</cfscript>
<cfdump var=#MyDoc#>
0
 
LVL 17

Expert Comment

by:Tacobell777
ID: 12210041
You can for example use
<cfxml variable="myNewXMLFile">
#oldXMLFile#
#variableContainingXMLToAppend#
</cfxml>

And write variables.myNewXMLFile back to a file.

Make sense?
0
 
LVL 1

Author Comment

by:Westside2004
ID: 12210156
So does that overwrite or append?

I am confused on how the #variableContainingXMLToAppend# will add to : #oldXMLFile#

??

-ws
0
 
LVL 17

Expert Comment

by:Tacobell777
ID: 12210179
oldXMLFile is the file you read in (i.e. the file you want to append to) you probably want to read the old file with cffile

variableContainingXMLToAppend is the part you want to append.

I guess you'd want to do something like

<cfxml variable="myNewXMLFile">
<root>
#oldXMLFile#
#variableContainingXMLToAppend#
</root>
</cfxml>

and make sure oldXMLFile is pointing to the elements below the root
0
 
LVL 1

Author Comment

by:Westside2004
ID: 12210503
Hi,

For example, lets say I have an xml file called "book.xml"

In it, I have the following code:

<?xml version="1.0" encoding="iso-8859-1"?>
   <book>
        <author>
             <fName>John</fName>
             <lName>Doe</lName>
       </author>
   </book>

So I basically want to be able to add an additional "Author" block to the existing xml file, not the xml opening tag, not add another root element, but just add another element called "author".  This data I want to append is coming from an HTML form.

So if it all worked correctly, I would get:

<?xml version="1.0" encoding="iso-8859-1"?>
   <book>
        <author>
             <fName>John</fName>
             <lName>Doe</lName>
        </author>
        <author>
             <fName>Jane</fName>
             <lName>Smith</lName>
        </author>  
   </book>

I hope that makes my question more clear..

thanks..
-ws
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 17

Expert Comment

by:Tacobell777
ID: 12213086
Read xml file into memory ...

create variableContainingXMLToAppend by encoding the form fields into xml

<cfxml variable="myNewXMLFile">
<book>
#oldXMLFile# (only output the author, you might need to loop, and use toString() if you still have an object here)
#variableContainingXMLToAppend# (if you have an xml object here you need to point to the author element only, and use toString())
</book>
</cfxml>

write xml back to file

IF you look at http://www.spike.org.uk/blog/ and scroll down to Copying XML Nodes between documents you'll fin dnaother method of doing it..
0
 
LVL 2

Accepted Solution

by:
dldeeds earned 225 total points
ID: 12213694
Here is an other approach. I copied the xml file you gave earlier as an example.

<?xml version="1.0" encoding="iso-8859-1"?>
   <book>
        <author>
             <fName>John</fName>
             <lName>Doe</lName>
       </author>
   </book>
   
I saved it on my local test machine and called it "Author.xml"... and ran the code below. The only thing I did not do was use a real form, I simulated that part, but it should give you an idea on how to add a node to an xml file.

When this example is run, simply hitting refresh will add the same "author" to the file. Be sure you have your checks in place to not allow duplicate submits, or that using the refresh button does not keep adding the same author.


<!--- Simulates names submitted via a form --->
<cfset formFname="FirstName">
<cfset formLname="LastName">

<!--- Read in the "Author.xml" file --->
<cffile action="read" file="D:\CFusionMX\wwwroot\MyTest\XmlTest\Author.xml" variable = "XmlIn" >

<!--- Parse the xml file into a cf xml document object --->
<cfset xmlData=xmlparse('#XmlIn#')>

<!--- Set up some var names to make processing xml roots and children easier --->
<cfset myRoot=xmlData.XmlRoot>
<cfset authorNode=myRoot.xmlChildren>

<!--- Calculate current number of Author nodes and increment by one for new Author index --->
<cfset newAuthor=(ArrayLen(authorNode))+1>

<!--- Set up new Author node using the index var just created --->
<cfset authorNode[newAuthor] = XmlElemNew(xmlData, "author") />

<!--- Set up Xml Children of Fname and Lname for the Author node --->
<cfset authorNode[newAuthor].XmlChildren[1] = XmlElemNew(xmlData, "fname") />
<cfset authorNode[newAuthor].XmlChildren[2] = XmlElemNew(xmlData, "lname") />

<!--- Assign values to the xmlText of the Children XmlElement in your new Author node --->
<cfset authorNode[newAuthor].XmlChildren[1].xmlText = "#formFname#" />
<cfset authorNode[newAuthor].XmlChildren[2].xmlText = "#formLname#" />

<!--- Did a cfdump to see what the object looked like ---
<cfdump var="#xmlData#">

<!--- Convert the new xml document object into a string and write the new Author.xml file to disk --->
<cfset XMLText=ToString(xmlData)>
<cffile action="write" file="D:\CFusionMX\wwwroot\MyTest\XmlTest\Author.xml" output="#XMLText#">

0
 
LVL 1

Author Comment

by:Westside2004
ID: 12215172
Hi,

Yes, that worked... thanks a bunch....

The only issue is, its not really an issue, but when I open up the xml file, its all on one line.

Is there a way to keep the formatting so its indented, etc

<?xml version="1.0" encoding="iso-8859-1"?>
   <book>
        <author>
             <fName>John</fName>
             <lName>Doe</lName>
       </author>
   </book>

I get it all on one line... if not, no big deal..... I will live with it, but having it structured in a hierachy is very helpful...

Thanks again!

-ws
0
 
LVL 2

Expert Comment

by:dldeeds
ID: 12223962
You could do something like this....

<cfset XMLText=ToString(xmlData)>
<cfset beginAuthor="#chr(9)#<author> #chr(13)#" & "#chr(10)#">
<cfset endAuthor="</author> #chr(13)#" & "#chr(10)#">
<cfset newXmlText1=Replace(XMLText, "<author>", beginAuthor, "ALL")>
<cfset newXmlText2=Replace(newXmlText1, "</author>", endAuthor, "ALL")>
<cffile action="write" file="D:\CFusionMX\wwwroot\MyTest\XmlTest\Author.xml" output="#newXmlText2#">

New var "beginAuthor" adds a TAB in front of the string <author> and a CFLR (carriage return line feed) at the end.
New var "endAuthor" adds a CFLR after the closing </author> tag.
Use the replace function to search the original xmlText string and replace all occurences of <author> with the new var and </author> etc.

I said you could do that...but I wouldn't.

For one thing, everytime you add a new author you will be adding a new tab and crlf to the "author" tags. You could probably do a bunch of coding to get around that, but I am not sure it is worth it.

I don't know what you are using to open the xml file, but most xml editors will open a "long string" xml file with the indenting and line breaks for the various nodes and elements, XmlSpy is pretty good one, and they have a free "home" version that is free, (http://www.altova.com/)

You can also use IE 6+. If you have IE 6 around, open your long string xml file with it. It will be "formatted" properly, (indents and line breaks, etc.). IE even lets you collapse the nodes if you want. Once opened in IE you can copy that format and paste into a text editor like notepad or textpad and it keeps the formatting, you will have to do a replace on the "-" (dashes) that IE puts in for collapsing the nodes, but that is pretty easy to do.

0
 
LVL 1

Author Comment

by:Westside2004
ID: 12224360
Hi,

Yah, thanks for that.. seems like a bit of work, maybe for a version 2 or something..

I dont think anyone will open the xml file unless its me.

If it works, then I should be fine without the indenting etc...

Thanks for the help...

-ws
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Periodically we have to update or add SSL certificates for customers. Depending upon your hosting plan you may be responsible for the installation and/or key generation. In the wake of Heartbleed many sites were forced to re-key. We will concen…
Introduction This article explores the design of a cache system that can improve the performance of a web site or web application.  The assumption is that the web site has many more “read” operations than “write” operations (this is commonly the ca…
The viewer will learn how to count occurrences of each item in an array.
The viewer will the learn the benefit of plain text editors and code an HTML5 based template for use in further tutorials.

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now