• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Deleting node returned from xmlSearch()

LEGEND ,
Sep 22, 2006 Sep 22, 2006

Copy link to clipboard

Copied

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


TOPICS
Advanced techniques

Views

315

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Sep 22, 2006 Sep 22, 2006

Copy link to clipboard

Copied

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)>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Sep 22, 2006 Sep 22, 2006

Copy link to clipboard

Copied

> 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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advisor ,
Sep 22, 2006 Sep 22, 2006

Copy link to clipboard

Copied

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.)

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Sep 23, 2006 Sep 23, 2006

Copy link to clipboard

Copied

LATEST
> 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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation