Solved

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

Posted on 2004-10-02
10
260 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
Save on storage to protect fatherhood memories

You're the dad who has everything. This Father's Day, make sure your family memories are protected. My Passport Ultra has automatic backup and password protection to keep your cherished photos and videos safe. With up to 3TB, you have plenty of room to hold the adventures ahead.

 
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

U.S. Department of Agriculture and Acronis Access

With the new era of mobile computing, smartphones and tablets, wireless communications and cloud services, the USDA sought to take advantage of a mobilized workforce and the blurring lines between personal and corporate computing resources.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Change local server setting in php 6 81
listing all functions in JavaScript 19 178
Problem to go to Web page 2 98
DNS @ Naked Domain Record 5 68
Preface This article introduces an authentication and authorization system for a website.  It is understood by the author and the project contributors that there is no such thing as a "one size fits all" system.  That being said, there is a certa…
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…
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:
Viewers will learn about basic arrays, how to declare them, and how to use them. Introduction and definition: Declare an array and cover the syntax of declaring them: Initialize every index in the created array: Example/Features of a basic arr…

920 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

13 Experts available now in Live!

Get 1:1 Help Now