Using StructAppend with two XML documents

I am trying to merge two XML document objects using StructAppend in ColdFusion MX 7 using StructAppend.  The two XML documents look something like this:

    firstDocument = XMLParse('<test><a>the letter a</a><b>the letter b</b></test>');
    secondDocument = XMLParse('<test><a>the letter a</a><b>the letter B</b><c>the letter c</c></test>');

When I try to call StructAppend(firstDocument, secondDocument, true), I receive the following error:

    WRONG_DOCUMENT_ERR: A node is used in a different document than the one that created it.

Any suggestions on how I can do this?
subject42Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

btrevarthenCommented:
ColdFusion doesl not allow a DOM to be directly assigned to another DOM.
Ben Forta has a post about this: http://www.sqlsource.org/blog/index.cfm?mode=e&entry=1654

You would need to construct a new DOM from scratch, using the child values of the XML you have, could get tricky.

-Bruce
trailblazzyr55Commented:
it is possible, however it's a little more complicated than, just using a StructAppend().

*first though, keep in mind the XML documents are accessed through Arrays, not structures, so StructAppend() wouldn't work anyway.

so.... you could write a function to handle this, and use then the function to accomplish your task...

I've done an example of how to parse them out and combined them, you can build the function, it is actually quite simple using the script below, just turn this into a function...

you can cut and paste this code to see it work, then you can put it into a function. You'll notice I modified your XML first and second document, to show a better example....

code
-----------------
<cfscript>
firstDocument = XMLParse('<test><a>the letter a</a><b>the letter b</b><d>the letter d</d></test>');
secondDocument = XMLParse('<test><a>the letter a</a><b>the letter B</b><c>the letter c</c></test>');

obj1=arraylen(firstDocument.xmlRoot.xmlchildren);
obj2=arraylen(secondDocument.xmlRoot.xmlchildren);

if(firstDocument.xmlRoot.xmlname eq secondDocument.xmlRoot.xmlname){
      TempArray1=ArrayNew(1);
      for(i=1;i lte obj1;i=i+1){
            TempArray1[i]=firstDocument.xmlRoot.xmlchildren[i].xmlname&'|'&firstDocument.xmlRoot.xmlchildren[i].xmltext;
      }
      TempArray2=ArrayNew(1);
      for(i=1;i lte obj2;i=i+1){
            TempArray2[i]=secondDocument.xmlRoot.xmlchildren[i].xmlname&'|'&secondDocument.xmlRoot.xmlchildren[i].xmltext;
      }

      TempXmlList1=arraytolist(TempArray1);
      TempXmlList2=arraytolist(TempArray2);
      NewTempXmlList=listappend(TempXmlList1,TempXmlList2);
      ParsedList='';
      for(i=1;i lte listlen(NewTempXmlList);i=i+1){
            if(not listfindnocase(ParsedList,listgetat(NewTempXmlList,i))){
                  ParsedList=listappend(ParsedList,listgetat(NewTempXmlList,i));
            }
      }

      ParsedList=listsort(ParsedList,'textnocase','asc');
      NewXmlDoc=XmlNew();
      RootName=firstDocument.xmlRoot.xmlname;
      NewXmlDoc.XmlRoot = XmlElemNew(NewXmlDoc,RootName);

      for(i=1;i lte listlen(ParsedList);i=i+1){
            element=listgetat(ParsedList,i);
            elementName=listfirst(element,'|');
            elementText=listlast(element,'|');
            NewXmlDoc[RootName].XmlChildren[i] = XmlElemNew(NewXmlDoc,elementName);
            NewXmlDoc[RootName].XmlChildren[i].XmlText = elementText;
      }
}else{
writeoutput('XML Root Names do not match, cannot combine documents!');
NewXmlDoc='Error Occured!';
}
</cfscript>

<cfdump var="#NewXmlDoc#">
---------------------

now with getting more indepth with the xml, meaning your xml documents have more to them and deeper structures, you'll have to modify this script for that, however this will give you a starting point as well as an answer to your queston...

also there may be a better way, but this is what I cam up with on the fly...

hope it helps,
~trail
subject42Author Commented:
The ColdFusion documentation states the following in "Modifying a ColdFusion XML Object":

    StructAppend:  Appends a document fragment XML document object to another XML document object.

Has anyone successfully used that, or is the documentation full of it?
trailblazzyr55Commented:
I haven't seen structappend() used for editing or merging xml documents...

here's a little tutorial on creating xml docs with coldfusion

http://tutorial97.easycfm.com/

I know it's not exactly what you're looking for but it gives you a little more insight...

also I've read the "Modifying a ColdFusion XML Object" and it doesn't limit you to using structures, you'll see arrays functions are in there as well. And

For what you're doing I haven't seen structappend() work though....

have you tried the example I posted, that does work for what you're trying to do....

and before i forget...
when reading through the "Modifying a ColdFusion XML Object" on livedocs, read the section labeled
"Adding, deleting, and modifying XML elements"

you'll see there's only specific instances where struct functions are used, everything else is with array and xml functions...

~trail

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Web Servers

From novice to tech pro — start learning today.