tags:

views:

561

answers:

3

I need to walk a JDOM tree and make changes as I go along; at this point, changes are mostly adding new elements right now but could also include reordering elements or removing elements. All work is done on the same thread so there are no concurrency issues.

This turns out to be difficult because JDOM iterators can throw a ConcurrentModificationException if you try to add a node during traversal. From what I can see, JDOM uses lists instead of directly linking DOM nodes and this makes it difficult to do modifications on the fly.

I've seen a couple of recommendations on how to deal with this, such as deferring the adds until after the traversal is done, or building a new tree on the fly so that the traversed tree remains unchanged. These won't work for me because I need a consistent view of the tree as I modify it.

I'm beginning to suspect that JDOM just won't work here. Do any of the other Java DOM models make this easier? Or is there a way to do this in JDOM?

A: 

Is there a reason you can't simply do two passes?

Most algorithms I'm familiar with won't require more than 2 traversals when decorating a tree (ideally, your algorithm should need a pass for initial decoration and perhaps a second for resolving references after the decoration).

Martin
Don't think that will work well. I'm providing the ability to define transformations at each node and the scripting model allows the rest of the tree to be examined during the transformation. Any kind of deferred update means the script writer need to deal with this.
jdigital
What technique would you suggest for decorating a JDOM node (Element)?
jdigital
A: 

Since you are open to using other models, you might consider Elliotte Rusty Harold's XOM API. It's rock solid, and won't allow you to create an invalid XML structure.

erickson
Can it handle this task?
jdigital
Yes; it doesn't expose iterators, so there's no chance of getting a concurrent modification exception. Traversal of child nodes is by their node index.
erickson
A: 

I've come up with what looks like an easy solution using JDOM. Rather than using the JDOM iterator directly, I use the iterator to create a list of nodes and then traverse using this list. Since this list is not "live", my scripts can modify the tree (and see the changes) without affecting the traversal. The traversal won't see structural changes but that should not be a problem.

jdigital