Deep copy an XML node in Saxon Java external function - java

I'm writing a Java external function that is supposed to be called from an XSLT stylesheet. I intend to return a modified node passed to my function as a parameter. However, I cannot deep copy a node since I'm getting The Saxon DOM cannot be updated. (I think the exception is a bit misleading since I'm not trying to modify a Saxon node). So my question is: what's the best way to utilize external function input nodes in order to return a modified version of it (e.g. adding an additional text node as a child)
Thanks in advance!

My first reaction would be that manipulating XML node trees is much better done in XSLT than in Java, so calling extension functions in order to do node manipulation seems very strange. In particular, "adding an additional text node as a child" is what XSLT was designed to do, so it seems very odd to call Java to do it.
Any code you do write in Java to manipulate nodes is going to be dependent on the tree model used. From the error message, it sounds as if you're probably building the tree initially using Saxon's TinyTree model, and then wrapping the TinyTree nodes in a DOM wrapper for the benefit of your Java code. The DOM wrapper will give you a DOM interface for retrieval/navigation, but not for update, because the TinyTree is immutable.

Unfortunately, the following code fails:
DOMWriter w = new DOMWriter();
w.setNode(programmaticallyCreatedNode);
tinyTreeNode.copy(w, CopyOptions.ALL_NAMESPACES, 0);
with (I'm using Saxon 9.1.0.8)
java.lang.NullPointerException
at net.sf.saxon.dom.DOMWriter.startElement(DOMWriter.java:103)
at net.sf.saxon.tinytree.TinyElementImpl.copy(TinyElementImpl.java:280)
...
I copied the node with:
DOMWriter w = new DOMWriter();
w.setNode(parentElementProgramaticallyCreated);
Element toCopy = ...;
((ElementOverNodeInfo)toCopy).getUnderlyingNodeInfo().copy(w, NodeInfo.ALL_NAMESPACES, false, 0);
Brief look at the code showed me that the NPE is because of not initialized namePool field in DOMWriter. Maybe I'm doing something completely wrong, but my intuition told me that copying a node should be somewhat simple.
Btw, I'm not tied to using DOM with Saxon, anything that would allow me receive a list of elements, read basic info from them (I was not able to quickly figure out how to get a list of attributes with their values from TinyElementImpl) and construct/copy nodes will serve my purpose. Again, I'm doing some complicated logic with attribute values in Java and depending on the result return a rearranged XML tree. That would be really painful to do it in plain XSLT.

Related

How to traverse an Abstract Syntax Tree object in python using javalang module?

I'm using javalang module (https://github.com/c2nes/javalang) to analyze a java code. I have no knowledge about parsing or static code analysis.
Example:
tree = javalang.parse.parse("-javacodelocation-")
for path,node in tree:
print path,node
This traverses through the tree and displays the path and the node name.
node.children()
gives all children of the iterator node.
I really can't figure how to traverse through this tree object properly and what all more information I can gather from the given Java code using this tree object.
Basically I just want to know more attributes,methods etc of the iterator node.
I tried using the dir(), still couldn't figure out anything useful
This is what I've implemented till now.
https://github.com/MokshTalreja/JavaCodeAnalyzer

Can we directly point to a node from Eclipse AST instead of visiting all the nodes

I am trying to parse a java file using Eclipse JDT's AST. ASTVisitor provides a nice API to traverse all the nodes and work with the node which we want. Now what I want is, can we go to a target node, let say of type MethodDeclaration or all the nodes of that type, instead of traversing all the nodes? Because this reduces time if I have to get all the nodes of a particular type in a whole package. Thanks in advance.
Finding all nodes of a given type inherently is traversing. ASTVisitor is suitable for this exact task.
If you are concerned about unnecessary traversal below the node you are interested in, just return false from the corresponding visit() method, and the visitor will not descend into children of the current node.
I'd be surprised, though, if traversing actually were a performance bottleneck. Creating the AST in the first place is more expensive than that.
If you only want to address few nodes (identified, e.g., by a name pattern), then performing a search (which relies on an index) could perhaps be faster, but this probably pays off only if a significant number of files can be skipped entirely.
Finally, as you mention MethodDeclaration: perhaps you don't even need AST but the Java Model (which is much more light weight) is sufficient for your task?

Java tree with N leaves?

I'm solving a Java problem which needs a java implementation of a tree with N leaves. For that, i decided to use XML Dom tree to represent the problem.
Is that possible with Dom4j ?
The problem is basically a tree of game which represents all moves to calculate the minimum number of moves required to win the game. Is that any useful sample for Dom4j ? Thanks.
I will attempt to answer but with some considerations in mind:
First of all to directly answer your question about whether it is possible to use a XML Dom tree to represent the problem? - Yes, it would be possible but in my opinion using an XML DOM tree to represent a data structure is not so natural (in fact I could also call it an overkill) unless you want to serialise that data structure to the disk or across the network as a result of an API call.
Examples are present here : http://dom4j.sourceforge.net/dom4j-1.6.1/guide.html
A cleaner and more simpler alternative would be to define a Node class like below:
class Node
{
int value; //assuming the node holds an integer value
List<Node> childNodes; // these are the N child nodes.
}
Your game algorithm can then iterate through the list of child nodes to perform it's computation logic.
One limitation that may appear with the above definition is that in case you want to search for a particular child node you need to iterate over the list - while in case you use DOM4j you could use XPath. But using DOM and XPath have their own limitations in terms of memory consumption - refer to this for details.
The simplistic data structure mentioned however above would not have the same memory implications - also it would be easier to manipulate the data structure during the computation process.
Hope this helps.

How to serialise an antlr3 AST

I have just started using antlr3 and am trying to serialize the AST output of a .g grammar.
Thanks,
Lezan
As Vladimir pointed out, you can use a a custom AST node class that has serialize capabilities builtin. You could also use a tree adaptor to create the types of nodes you need.
If you only need serialization, and not de-serialization, you could probably just do:
ast.toStringTree()
The above will give you a LISP like tree structure. An easy way to do serialization would be to use that in combination with a custom AST node class with an overridden toString(). Since toStringTree() uses the node's toStringTree method, it'll essentially serialize whatever you put in toString. Make its output sufficient and useful and you should be set.
CommonTree nodes produced by Parser are not Serializable.
I'd suggest you to serialize Tokens and use a secondary grammar for parsing the (deserialized) stream of Tokens later. In the book (The Definitive ANTLR Reference), in the Quick Tour for Impatient chapter, Terence Parr gives exactly this scenario -- without serialization though, but serialization is trivial for tokens as they are just text.
My understanding also that you can replace the Tree class with your own:
options {
ASTLabelType = MyOwnTreeClass;
}
But I haven't tried it.

Existing implementations of Trees in Java?

I'm looking for any implementation of a pure Tree data structure for Java (that aren't graphical ones in java.awt), preferably generic.
With a generic tree I'd like to add elements that are not supposed to be sorted and do something like this:
TreeNode anotherNode = new TreeNode();
node.add(anotherNode);
…and then I'd like to traverse the nodes (so that I can save and preserve the structure in a file when I load the tree from the same file again).
Anyone knows what implementations exist or have any other idea to achieve this?
You can use the DefaultMutableTreeNode defined in the javax.swing.tree package. It contains methods getUserObject() and setUserObject(Object) allowing you to attach data to each tree node. It allows an arbitrary number of child nodes for each parent and provides methods for iterating over the tree in a breadth-first or depth-first fashion (breadthFirstEnumeration() / depthFirstEnumeration()).
Also note that despite being resident in the javax.swing.tree package this class does not contain any UI code; It is merely the underlying model of JTree.
Scala has a nice Tree data structure. It's a "General Balanced Tree." It's not exactly Java, but it's close, and can serve as a good model.
It is hard to believe, given how much is in the base Java libraries, but there is no good generic Tree structure.
For a start, the TreeSet and TreeMap in the runtime are red-black-tree implementations.
Assuming you don't want to store arbitrary Java objects on the nodes, you could use the W3C DOM. It even comes with its own serialization format (I forget what it's called :-).

Categories