4 Replies Latest reply on Sep 23, 2006 2:53 AM by Newsgroup_User

    Deleting node returned from xmlSearch()

    Level 7
      G'day
      Consider this sample XML:

      <aaa id="1">
      <bbb id="2">
      <ccc id="3"></ccc>
      <ccc id="4"></ccc>
      <ccc id="5"></ccc>
      </bbb>
      <bbb id="6"></bbb>
      </aaa>

      I am using the following xpath to single out a specific node:

      //ccc[@id='4']

      Having located that node, I need to delete it.

      The best solution I've come up with is this:

      <cfset a = xmlSearch(x, "//ccc[@id='4']/preceding-sibling::ccc")>
      <cfset i = xmlChildPos(a[1].xmlParent, "ccc", arrayLen(a)+1)>
      <cfset arrayDeleteAt(x.aaa.bbb.xmlChildren, i)>

      Now this seems like a really silly approach (I'm also not certain it's
      particularly robust). I would have thought - given I have the exact node I
      want to delete - I should be able to do something along the lines of:

      <cfset someDeleteFunction(a[1])>

      Anyone done this sort of thing before?

      PS: pls resist the temptation to offer suggestions that involve a loop
      going "Is it this one? No. This one? No. This one? Yes! OK, delete
      it". This does not - in my mind - constitute an appropriate solution (and
      I've already thought of it, and cringed even more than with my current
      "solution").

      Cheers.

      --
      Adam


        • 1. Re: Deleting node returned from xmlSearch()
          Level 7
          The problem is that the xmlSearch does not return a reference to the
          node(s), but rather an array of copies of the nodes that match the xpath
          expression.

          I have found XSLT to be a much cleaner way to do this kind of XML
          modification.

          <cfsavecontent variable="y">
          <?xml version="1.0" encoding="iso-8859-1"?>

          <xsl:stylesheet version="1.0"
          xmlns:xsl=" http://www.w3.org/1999/XSL/Transform">

          <!-- XSL code to modify the XML in the desired manner -->

          </xsl>
          </cfsavecontent>


          <cfset a = xmlTransform(x,y)>
          • 2. Re: Deleting node returned from xmlSearch()
            Level 7
            > The problem is that the xmlSearch does not return a reference to the
            > node(s), but rather an array of copies of the nodes

            No it doesn't. They're references to the nodes, not copies. Easy to test:
            add/update/delete an attribute in the array, and it is also reflected in
            the original XML object.

            Along these lines, one can actually do a structClear() on the array element
            which gets rid of what's there (so kinda OK), but leaves a null node in the
            XML doc, rather than deleting it (which is actually OK for my immediate
            requirement, but not a "complete" answer).


            > I have found XSLT to be a much cleaner way to do this kind of XML
            > modification.

            I considered this approach. It still smacks me as a variation of the old
            "loop over it until you find it" routine. Which just strikes me as
            *wrong*, for a simple node deletion.

            My rule of thumb is I avoid looping if I'm not performing the given action
            (ie: the code in the loop) on the majority of the items being looped over.
            Sure the XSLT abstracts the looping away from immediate scrutiny, but it's
            still happening.

            But anyway, thanks for coming back to me. It's good to know how other
            people deal with these things.

            --
            Adam
            • 3. Re: Deleting node returned from xmlSearch()
              MikerRoo Level 1
              Given the limitations of xmlChildPos() and Adobe XPath, I believe that yours is the most concise, XML, way to delete a node by id (unless java offers something better).

              But, we have found it cleaner and easier to do similar edits on the XML text using an REReplace. (We have no child nodes or CDATA to contend with.)
              • 4. Re: Deleting node returned from xmlSearch()
                Level 7
                > But, we have found it cleaner and easier to do similar edits on the XML text
                > using an REReplace. (We have no child nodes or CDATA to contend with.)

                Hi Mike.
                I think your opinion of CF's XML support matches mine, by the sounds of it.
                It seems a bit of a superficial nod, rather than a well-considered
                implementation.

                I thought about the regex approach. Indeed for the situation in front of
                us where we know (and are in control of) the structure of the XML and the
                node we're removing is always going to be fairly simple, the regex solution
                would have worked.

                Cheers.

                --
                Adam