Extract Java element based on its corresponding XML element

209 Views Asked by At

I have a XML file resulted from an input java file. I also have xPath expressions for the XML file.

I need a function that receives one xPath expression and return its java element (in the abstract syntax tree). I tried the below code:

  1. First extract XML element based on the input xPath expression.

    XPath xPath =  XPathFactory.newInstance().newXPath();
    String query = "//unit[1]/unit[1]/class[1]/block[1]/function[6]"; //a method
    Node node = (Node) xPath.compile(query).evaluate(XmlDocument, XPathConstants.NODE);
    
  2. However, I do not know how to link extracted XML node to Java element in the source code.

PS: The reslut should be a node in the abstract syntax tree. I have AST created by spoon. Therefore, in the above example, I want to extract related CtMethodImpl.

node.getTextContent() is not the answer as it is possible that there is more than one instance with the similar text content.

1

There are 1 best solutions below

0
On

To the best of my knowledge there is no 'direct' way of doing this.

This: "//unit[1]/unit[1]/class[1]/block[1]/function[6]" is what we call a signature in the sense that it uniquely identifies an element (somehow).

What I would do is to create a spoon processor and go through the entire AST checking each element to see if it matches the signature.

public class ProcessorExample <E extends CtElement> extends AbstractProcessor<E> {

    HashMap<String, Node> nodes;
    //Sets your XML Nodes here, sorted by signature
    public void setNodes(HashMap<String, Node> nodes) {
        this.nodes = nodes;
    }

    @Override
    public void process(E element) {
        if (nodes.containsKey(signature(element))) {
            Node n = nodes.get(signature(element));
            //YOU FOUND IT!
        }
    }

    private String signature(E element) {
        //YOU MUST PROVIDE THIS IMPLEMENTATION
        //TO MATCH YOUR "//unit[1]/unit[1]/class[1]/block[1]/function[6]"
        //KIND OF SIGNATURE
        return null;
    }
}