8 Replies Latest reply on Sep 23, 2013 12:16 PM by Aegis Kleais

    How do I modify XML? I know where it is, but cannot figure out how to modify it

    Aegis Kleais Level 3

      I have this XML data, and I know there is a node called <group> that has an attribute of tplID with a value of 'alpha'.  There ARE other <group> nodes at the same (and different) hierarchy level, but they should at least have a different value in their 'tplID' attribute.

       

      Thing is, how would I go about, say, removing every child node from the XML document for the node that is specifically : <group tplID="alpha"> ?

       

      I can target him with XPath like <cfset test = xmlSearch( xmlDocObject, '/template//group[@tplID="alpha"]' ) />

       

      But this just returns me an array containing the XML that matches that.  Any ideas?

        • 1. Re: How do I modify XML? I know where it is, but cannot figure out how to modify it
          p.sim Level 3

          That is correct. It returns an array. The next step is to remove the child nodes you mentioned. Then, you construct those pieces back together as a single XML document.

           

          http://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSc3ff6d0ea77859461172e0811cbec22c24 -78e5.html

          • 2. Re: How do I modify XML? I know where it is, but cannot figure out how to modify it
            Aegis Kleais Level 3

            Hey p.sim,

             

            I've read the documentation on CF's XML Functions, but nothing has come across as a viable solution. I don't think they are capable of doing what I'm looking for while keeping the data as pure XML.  I was mulling over useing a toString() on the XML to convert it to text and then perform search and replaces, but it's just as convoluted a process.

             

            I can use xmlSearch() to find the node that matches the ID provided and get back a copy of its XML.  But I cannot derive any information about that XML node within the master XML doc object so as to reference it, or be able to modify nodes before/after/within it.

             

            It's part of a custom template engine I'm building.  You have this base XML which defines elements that are generated to create a page's HTML, and then you have this "Merger XML" which is a series of commands that modify the base XML.  That's where I'm at right now.  This merger XML has commands in it like: insertNode, removeNode, etc.

             

            So for example, there could be a command like:

             

            <insertNode tplID="abc" direction="before">

                 <newNode name="this" value="that" />

            </insertNode>

             

            So when it gets to this command in the Merger XML, it must be able to look through the base XML and say "Where is there a node that has the attribute of tplID and a value of abc?  OK, THERE it is.  Now I want to insert the value of my child node (<newNode>) before this point in the base XML.

             

            The problem is I can use xmlSearch and XPath to FIND these locations in the base XML, but I have no idea how to go forwad from there.  How do I get the reference point so I can then proceed to modify the base XML?  All xmlSearch() gets me is a copy of the matching XML of my XPath query, as expected.

            • 3. Re: How do I modify XML? I know where it is, but cannot figure out how to modify it
              Aegis Kleais Level 3

              ------------------------------------------------------------------------------------------ --------------

              *** UPDATE ***

              ------------------------------------------------------------------------------------------ --------------

               

              OK, I am getting somewhere.  I basically am using the base XML's .xmlChildren() which returns an array of nodes.  This gives me a location reference.  When I search for a matching groupID, I capture the array index of where it is found.  I have successfully been able to reference the group that was designated for clearing, and remove the children as intended.

               

              I am now working on the appendGroup/prependGroup functions, which take their children nodes and either append or prepend them into the designated location's child nodes, but CF is returning the following error:

               

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

               

              It seems that I cannot simply insert XML into the base XML template, but instead have to import it.  Am attempting to find resources to figure out how to do that, since I'm sure that any command which brings in new data to the base XML will have this issue.

              • 4. Re: How do I modify XML? I know where it is, but cannot figure out how to modify it
                Adam Cameron. Level 5

                Hmmm... I googled "coldfusion import xml into another xml doc" and the first match (Ben Nadel's blog) pretty much explains what you need to do, I think..?

                 

                --

                Adam

                • 5. Re: How do I modify XML? I know where it is, but cannot figure out how to modify it
                  BenNadel

                  Adam, from what I remember, I ended up going one of two routes:

                   

                  1) "Recreate" the imported nodes in the target document:

                   

                  http://www.bennadel.com/blog/1532-Copy-Import-XML-Nodes-Into-A-ColdFusion-XML-Document.htm

                   

                  2) Reach into the Java layer to actually change the owner document of the nodes:

                   

                  http://www.bennadel.com/blog/701-Copying-Children-From-One-ColdFusion-XML-Document-To-Anot her.htm

                   

                  To be honest, I've never really had to use any of this in production; so, I don't fully undersand the trade-offs of #2. For example, do these nodes get ripped out of their original document? I would guess yes, but am not sure.

                   

                  That said, this sounds like a nice feature to add to my old XDom project: https://github.com/bennadel/XDom.cfc .

                   

                  Cheers,

                  Ben Nadel

                  1 person found this helpful
                  • 6. Re: How do I modify XML? I know where it is, but cannot figure out how to modify it
                    Adam Cameron. Level 5

                    > It's part of a custom template engine I'm building.

                     

                    What is this "custom template engine" going to do?

                     

                    I have a supsicion it might be re-treading well-trod ground (of course that's just a guess)?

                     

                    --

                    Adam

                    • 7. Re: How do I modify XML? I know where it is, but cannot figure out how to modify it
                      Aegis Kleais Level 3

                      I basically created a temp XML document and put the XML from both files (base and page) into 1, so that I could freely move data around as desired.  It got me past that first hurdle.

                       

                      Ben comments his code very well, but he is far above the level of ColdFusion developer I am.  It would be like a grade school math student attending a class in advanced trigonometry.  It's only a solution if you can comprehend what he's doing at each stage, and even with his comments, I was not able to follow his solution.  It can be as simple as verbage throwing me off; if we're not on the same page, I simply can't follow.

                       

                      So for example, I have a structure now like this:

                       

                      (LOCAL.mergedXML):

                      <root>

                           <template>

                                <!-- The base template XML is here. -->

                           </template>

                           <pageTemplate>

                                <!-- The merger template XML is here. -->

                           </pageTemplate>

                      </root>

                       

                      I was successfully able to use arrayAppend() in order to append information from the <pageTemplate> node into the <template> node, but oddly, I am now executing the next command, to prepend data, and when I attempt to do so, ColdFusion is throwing an error.  The code it errors on is:

                       

                      <cfset arrayPrepend( LOCAL.mergedXML.root.template.xmlChildren[ LOCAL.tplVars.matchedIndex ].xmlChildren, LOCAL.tplVars.prependContent ) />

                       

                      I have verified through isArray() that both values are arrays, but CF returns a: java.lang.ClassCastException error with an empty message value.

                       

                      As for why I'm building my own template engine, Pablo Picasso once said "I am always doing that which I cannot do, in order that I may learn it".  I understand coder's desire not to "reinvent the wheel", however standing on the shoulders of those who came before me may get me to a solution faster, but does not expand my skillsets as a developer.

                      • 8. Re: How do I modify XML? I know where it is, but cannot figure out how to modify it
                        Aegis Kleais Level 3

                        OK, I figured this one out.  Once I figured out how to reference the base XML location, I simply ensured to use the .xmlChildren() function in tandem with the array methods provided by ColdFusion, and that seems to have gotten me to where I want to be.  Appreciate the help guys.