Content
Overview
Checkstyle uses XPath queries in two main ways:
- Violation suppression — via SuppressionXpathFilter and SuppressionXpathSingleFilter, which let you suppress specific violations by matching AST nodes with XPath expressions.
- Custom checks — via the MatchXpath check, which fires a violation on every AST node matched by a given XPath query, allowing users to write custom style rules without writing Java code.
This page explains the XPath version supported, how Checkstyle's AST maps to XPath,
the @text attribute, supported axes, and how to use the CLI tools to
build and test XPath queries.
XPath Version
Checkstyle supports XPath 3.1 via the Saxon-HE library. For the exact Saxon-HE version bundled with your Checkstyle release, see the dependency report and the corresponding documentation at saxonica.com.
Note that XPath 2.0 and XPath 1.0 are not fully backwards compatible. For example,
a numeric comparison such as "4" > "4.0" yields different results
depending on the version. Always write queries with XPath 3.1 semantics in mind.
AST and XPath
Checkstyle parses each Java source file into an Abstract Syntax Tree (AST).
XPath queries operate on this tree. Each node in the tree corresponds to a Java
language construct and has a token type (e.g. CLASS_DEF,
METHOD_DEF, IDENT).
You can print the full AST of any Java file using the -T option of the Checkstyle command line tool:
$ java -jar checkstyle-X.XX-all.jar -T Main.java
CLASS_DEF -> CLASS_DEF [1:0]
|--MODIFIERS -> MODIFIERS [1:0]
| `--LITERAL_PUBLIC -> public [1:0]
|--LITERAL_CLASS -> class [1:7]
|--IDENT -> Main [1:13]
`--OBJBLOCK -> OBJBLOCK [1:18]
|--LCURLY -> { [1:18]
|--METHOD_DEF -> METHOD_DEF [2:4]
| |--MODIFIERS -> MODIFIERS [2:4]
| | `--LITERAL_PUBLIC -> public [2:4]
| |--TYPE -> TYPE [2:11]
| | `--IDENT -> String [2:11]
| |--IDENT -> sayHello [2:18]
| |--LPAREN -> ( [2:26]
| |--PARAMETERS -> PARAMETERS [2:27]
| | `--PARAMETER_DEF -> PARAMETER_DEF [2:27]
| | |--MODIFIERS -> MODIFIERS [2:27]
| | |--TYPE -> TYPE [2:27]
| | | `--IDENT -> String [2:27]
| | `--IDENT -> name [2:34]
| |--RPAREN -> ) [2:38]
| `--SLIST -> { [2:40]
| |--LITERAL_RETURN -> return [3:8]
| | `--SEMI -> ; [3:31]
| `--RCURLY -> } [4:4]
`--RCURLY -> } [5:0]
You can then use the -b option to test an XPath query against a file and see which AST nodes it matches:
$ java -jar checkstyle-X.XX-all.jar Main.java -b "//METHOD_DEF[./IDENT[@text='sayHello']]"
CLASS_DEF -> CLASS_DEF [1:0]
`--OBJBLOCK -> OBJBLOCK [1:18]
|--METHOD_DEF -> METHOD_DEF [2:4]
Additionally, Checkstyle provides a GUI application that displays the AST interactively, making it easier to explore the tree structure and build XPath queries.
For full XPath syntax reference, see XPath Syntax. For XPath functions, see XSLT/XPath Reference.
The @text Attribute
Checkstyle extends XPath with a special @text attribute that exposes
the source text of an AST node. This is available only on certain token types that
carry meaningful text — for example, IDENT nodes expose the identifier
name, and STRING_LITERAL nodes expose the literal value.
For the full list of token types that support @text, see
XpathUtil in the Checkstyle source.
Example — match any method named foo:
//METHOD_DEF[./IDENT[@text='foo']]
Example — match any method named test or foo:
//METHOD_DEF[./IDENT[@text='test' or @text='foo']]
Supported XPath Axes
Checkstyle supports the following XPath axes when querying the AST:
ancestorancestor-or-selfattributechilddescendantdescendant-or-selffollowingfollowing-siblingparentprecedingpreceding-siblingself
Using XPath for Suppressions
XPath-based suppression allows you to suppress violations on specific AST nodes rather than by line number or message pattern. This is more robust because it does not break when code is reformatted or lines are added.
There are two filters available:
-
SuppressionXpathFilter
— uses a separate XML suppressions file with
suppress-xpathelements. - SuppressionXpathSingleFilter — configured inline in the Checkstyle config file, suppresses violations matching a given check and XPath query.
The command line tool can automatically generate XPath suppressions for detected violations using the -g flag:
$ java -jar checkstyle-X.XX-all.jar -c config.xml -g Main.java
Note that XPath-based suppression does not support all checks. Checks that do not log violations against an AST node (e.g. file-level checks) cannot be suppressed this way. See SuppressionXpathFilter for the full list of incompatible checks.
Using XPath for Custom Checks
The MatchXpath check fires a violation on every AST node matched by a given XPath query. This allows users to implement custom style rules entirely in configuration, without writing any Java code.
It is recommended to always provide a custom violation message using the
message element with key matchxpath.match to explain
what is disallowed and what to use instead.
Example — require public methods to appear before private methods:
<module name="Checker">
<module name="TreeWalker">
<module name="MatchXpath">
<property name="query"
value="//METHOD_DEF[.//LITERAL_PRIVATE
and following-sibling::METHOD_DEF[.//LITERAL_PUBLIC]]"/>
<message key="matchxpath.match"
value="Private methods must appear after public methods"/>
</module>
</module>
</module>
Example — disallow parameterized constructors:
<module name="Checker">
<module name="TreeWalker">
<module name="MatchXpath">
<property name="query"
value="//CTOR_DEF[count(./PARAMETERS/*) > 0]"/>
<message key="matchxpath.match"
value="Parameterized constructors are not allowed"/>
</module>
</module>
</module>
Example — enforce use of var for new instance creation:
<module name="Checker">
<module name="TreeWalker">
<module name="MatchXpath">
<property name="query"
value="//VARIABLE_DEF[./ASSIGN/EXPR/LITERAL_NEW
and not(./TYPE/IDENT[@text='var'])]"/>
<message key="matchxpath.match"
value="New instances should be created via var keyword"/>
</module>
</module>
</module>
Example — disallow classes with more than one constructor:
<module name="Checker">
<module name="TreeWalker">
<module name="MatchXpath">
<property name="query"
value="//CLASS_DEF[count(./OBJBLOCK/CTOR_DEF) > 1]"/>
<message key="matchxpath.match"
value="Classes with more than 1 constructor are not allowed"/>
</module>
</module>
</module>
See the full MatchXpath examples for more patterns.






