CtPath (javadoc) defines the path to a CtElement (javadoc) in a model. For example, .spoon.test.path.Foo.foo#body#statement[index=0] represents the first statement of the body of method foo.

A CtPathis based on: names of elements (eg foo), and roles of elements with respect to their parent (eg body). A role is a relation between two AST nodes. For instance, a "then" branch in a if/then/else is a role (and not an node). All roles can be found in CtRole. In addition, each getter or setter in the metamodel is annotated with its role.

To build a path, there are several possibilities:

  • method getPath in CtElement
  • CtPathStringBuilder (javadoc). it creates a path object from a string according to a syntax inspired from XPath and CSS selectors.
  • the low-level CtPathBuilder (javadoc), it defines a fluent api to build your path.

To evaluate a path, ie getting the elements represented by it, use evaluateOn(List<CtElement>)

path = new CtPathStringBuilder().fromString(".spoon.test.path.Foo.foo#body#statement[index=0]");
List<CtElement> l = path.evaluateOn(root)


CtPathStringBuilder exposes only one method to build a path from a string.

  • fromString(String) (javadoc) builds a path from a string representation.

For instance, if we want the first statement in the body of method foo, declared in the class spoon.test.path.Foo.

new CtPathStringBuilder().fromString(".spoon.test.path.Foo.foo#body#statement[index=0]");


CtPathBuilder exposes the following methods:

  • name(String, String[]) (javadoc) adds a name matcher to the current path.
  • type(Class, String[]) (javadoc) matches on element of a given type.
  • role(CtPathRole, String[]) (javadoc) matches on elements by their role (where CtPathRole gives all constants supported).
  • wildcard() (javadoc) matches only on elements child of current one.
  • recursiveWildcard() (javadoc) matches on any child and sub-children.

For instance, if we want all elements named by "toto" and with a default value in a project. Use CtPathBuilder like the example below.

new CtPathBuilder().recursiveWildcard().name("toto").role(CtPathRole.DEFAULT_VALUE).build();

The corresponding string syntax would be:

new CtPathStringBuilder().fromString("**.toto#defaultValue");

The order in instructions is important and have a meaning. These two pieces of code below have a different meaning. The first one takes all toto elements in the project. The second takes the first element named by "toto" at the root of your project and after, makes a search recursively in your project according to the rest of your path request.

new CtPathBuilder().recursiveWildcard().name("toto")
new CtPathBuilder().name("toto").recursiveWildcard()