Class DomXPathRule

java.lang.Object
net.sourceforge.pmd.properties.AbstractPropertySource
net.sourceforge.pmd.lang.rule.AbstractRule
net.sourceforge.pmd.lang.xml.rule.DomXPathRule
All Implemented Interfaces:
net.sourceforge.pmd.lang.rule.Rule, net.sourceforge.pmd.properties.PropertySource

public class DomXPathRule extends net.sourceforge.pmd.lang.rule.AbstractRule
XPath rule that executes an expression on the DOM directly, and not on the PMD AST wrapper. The XPath expressions adheres to the XPath (2.0) spec, so they can be tested in any existing XPath testing tools instead of just the PMD designer (google "xpath test"). Usage of this class is strongly recommended over the standard XPathRule, which is mostly useful in other PMD languages.

Differences with XPathRule

This rule and XPathRule do not accept exactly the same queries, because XPathRule implements the XPath spec in an ad-hoc way. The main differences are:
  • XPathRule uses elements to represent text nodes. This is contrary to the XPath spec, in which element and text nodes are different kinds of nodes. To replace the query //elt/text[@Text="abc"], use the XPath function text(), eg //elt[text()="abc"].
  • XPathRule adds additional attributes to each element (eg @BeginLine and @Text). These attributes are not XML attributes, so they are not accessible using DomXPathRule rule. Instead, use the XPath functions pmd:startLine(node), pmd:endLine(node) and related. For instance, replace //elt[@EndLine - @BeginLine > 10] with elt[pmd:endLine(.) - pmd:startLine(.) > 10].
  • XPathRule uses an element called "document" as the root node of every XML AST. This node does not have the correct node kind, as it's an element, not a document. To replace /document/RootNode, use just /RootNode.
  • XPathRule ignores comments and processing instructions (eg FXML's <?import javafx.Node ?>). This rule makes them accessible with the regular XPath syntax. The following finds all comments in the file:
    
      //comment()
     
    The following finds only top-level comments starting with "prefix":
    
      /comment()[fn:starts-with(fn:string(.), "prefix")]
     
    Note the use of fn:string. As an example of matching processing instructions, the following fetches all <?import ... ?> processing instructions.
    
      /processing-instruction('import')
     
    The string value of the instruction can be found with fn:string.

Additionally, this rule only supports XPath 2.0, with no option for configuration. This will be bumped to XPath 3.1 in PMD 7.

Namespace-sensitivity

Another important difference is that this rule is namespace-sensitive. If the tested XML documents use a schema (xmlns attribute on the root), you should set the property defaultNsUri on the rule with the value of the xmlns attribute. Otherwise node tests won't match unless you use a wildcard URI prefix (*:nodeName).

For instance for the document


 <foo xmlns="http://company.com/aschema">
 </foo>
 
the XPath query //foo will not match anything, while //*:foo will. If you set the property defaultNsUri to "http://company.com/aschema", then //foo will be expanded to //Q{http://company.com/aschema}foo, and match the foo node. The behaviour is equivalent in the following document:

 <my:foo xmlns:my='http://company.com/aschema'>
 </my:foo>
 

However, for the document


 <foo>
 </foo>
 
the XPath queries //foo and //*:foo both match, because //foo is expanded to //Q{}foo (local name foo, empty URI), and the document has no default namespace (= the empty default namespace).

Note that explicitly specifying URIs with Q{...}localName as in this documentation is XPath 3.1 syntax and will only be available in PMD 7.

Author:
Clément Fournier
Since:
PMD 6.44.0
  • Field Summary

    Fields inherited from interface net.sourceforge.pmd.lang.rule.Rule

    VIOLATION_SUPPRESS_REGEX_DESCRIPTOR, VIOLATION_SUPPRESS_XPATH_DESCRIPTOR
  • Constructor Summary

    Constructors
    Constructor
    Description
     
     
    DomXPathRule(String xpath, String defaultNsUri)
     
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    apply(net.sourceforge.pmd.lang.ast.Node node, net.sourceforge.pmd.reporting.RuleContext ctx)
     
    void
    initialize(net.sourceforge.pmd.lang.LanguageProcessor languageProcessor)
     

    Methods inherited from class net.sourceforge.pmd.lang.rule.AbstractRule

    addExample, asCtx, buildTargetSelector, deepCopy, end, equals, getDescription, getExamples, getExternalInfoUrl, getLanguage, getMaximumLanguageVersion, getMessage, getMinimumLanguageVersion, getName, getPriority, getPropertySourceType, getRuleClass, getRuleSetName, getSince, getTargetSelector, hashCode, isDeprecated, setDeprecated, setDescription, setExternalInfoUrl, setLanguage, setMaximumLanguageVersion, setMessage, setMinimumLanguageVersion, setName, setPriority, setRuleClass, setRuleSetName, setSince, start

    Methods inherited from class net.sourceforge.pmd.properties.AbstractPropertySource

    definePropertyDescriptor, getOverriddenPropertiesByPropertyDescriptor, getOverriddenPropertyDescriptors, getPropertiesByPropertyDescriptor, getProperty, getPropertyDescriptor, getPropertyDescriptors, hasDescriptor, isPropertyOverridden, setProperty

    Methods inherited from class java.lang.Object

    clone, finalize, getClass, notify, notifyAll, toString, wait, wait, wait

    Methods inherited from interface net.sourceforge.pmd.properties.PropertySource

    definePropertyDescriptor, dysfunctionReason, getOverriddenPropertiesByPropertyDescriptor, getOverriddenPropertyDescriptors, getPropertiesByPropertyDescriptor, getProperty, getPropertyDescriptor, getPropertyDescriptors, hasDescriptor, isPropertyOverridden, setProperty
  • Constructor Details

    • DomXPathRule

      public DomXPathRule()
    • DomXPathRule

      public DomXPathRule(String xpath)
    • DomXPathRule

      public DomXPathRule(String xpath, String defaultNsUri)
  • Method Details

    • apply

      public void apply(net.sourceforge.pmd.lang.ast.Node node, net.sourceforge.pmd.reporting.RuleContext ctx)
    • initialize

      public void initialize(net.sourceforge.pmd.lang.LanguageProcessor languageProcessor)