> OK...I have the following Java code that I am now trying to convert to
> Jython. In particular, the NodeIterator is where I am getting stuck.
> In the Jython book page 469, entitled, "Functions On Iterables", I see the
> functions on the Java Iterator interface, but I don't know how to use this
> in Jython.
There are multiple things going on here.
First of all, NodeIterator is lying to you: it is *not* a java Iterator.
What I mean by this is that it does not implement the
When java classes implement the java.util.Iterator interface, jython
"automagically" recognises them as such, and permits you to use python
iteration semantics on them, e.g. for loops.
Consider the following code.
In jython, we create a java ArrayaList
>>> import java
>>> duck_typing = java.util.ArrayList()
And we add some strings to it
>>> duck_typing.add("if it looks like a duck")
>>> duck_typing.add("and walks like a duck")
>>> duck_typing.add("and talks like a duck")
>>> duck_typing.add("it probably is a duck")
Now we want to iterate over the contents of ArrayList, using the
So we create an Iterator.
>>> i = duck_typing.iterator()
We get its first element
u'if it looks like a duck'
We get its second element
u'and walks like a duck'
We get its third element
u'and talks like a duck'
We get its fourth element
u'it probably is a duck'
And then we reach the end of the sequence.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Java raises an exception to signify the end of the iteration. Python
does exactly the same thing, except that it raises a different
Jython "automagically" recognises java Iterators when used in for
loops. Consider this code
>>> for s in duck_typing.iterator():
... print s
if it looks like a duck
and walks like a duck
and talks like a duck
it probably is a duck
A: Every element of the array was printed
B: There was no exception when we reached the end.
This because jython "automagically" recognises the exception at the
end as being the end of the Iterator.
Java iterators work so well with python because python has an
identical concept, but with a slightly different API.
Java iterators work so well with python because the jython
implementers work hard on your behalf to make sure that you don't see
the gap between java and jython: stuff just works ;-)
But the DOM NodeIterator class you referred to earlier broke the
promise, because it is not a real java iterator: it does not implement
the java.util.Iterator interface.
It does not have a "next()" method. Instead, it has it's own custom
implementation of "iterator", which uses non standard method names.
Instead of the "next" method, it has a "nextNode" method. Also, it
does not raise an exception at end of the iterator, it returns null.
So jython cannot iterate over it in a for loop :-(
But all is not lost! Because we're working in a dynamic language, we
resolve that problem.
If we wrap the "nodeIterator" in a python iterator, we can make it
work. This class should do it (forgive the magic).
def __init__(self, domNodeIterator):
self.dni = domNodeIerator
nextNode = self.dni.nextNode()
if nextNode is not None: # java null is translated to None
So now, if you wrap the NodeIterator with a JyNodeIterator, it should
"just work", like this
for n in JyNodeIterator(TSS_EDA_Apps_NodeIterator):
if n.getNodeType() == Node.ELEMENT_NODE:
print "Encountered Element:", n.getNodeName()
elif n.getNodeType() == Node.TEXT_NODE:
print "Encountered Text:" n.getNodeName()
I haven't tested any of this code.
For those interested in behaviours like this, i.e. "automagically"
recognising capabilities (which is *not* duck-typing), I recommend
reading up on "Abstract Base Classes", a python 2.6 concept that will
be introduced to jython in jython 2.6.