code4craft/webmagic · error · IllegalArgumentException

XPath error!

Error message

XPath error!

What it means

Xpath2Selector's constructor compiles the XPath 2.0 expression with Saxon (init()). If the expression is syntactically invalid or not valid XPath 2.0, XPathExpressionException is wrapped into IllegalArgumentException "XPath error!". The selector can never be used once this fails.

Solutions

  1. Validate and fix the XPath string syntax; test it in a standalone Saxon/XPath 2.0 evaluator first.
  2. Ensure quotes inside the expression are balanced and escape embedded quotes properly in Java string literals.
  3. Remove or rewrite functions/syntax not available in XPath 2.0.
  4. Pre-compile expressions at startup (fail fast) and wrap construction in try-catch to surface the bad selector name.

Example fix

// before
new Xpath2Selector("//div[@class='item'");
// after
new Xpath2Selector("//div[@class='item']");
Defensive patterns

Strategy: try-catch

Try / catch

try {
    selector = new Xpath2Selector(xpathStr);
} catch (IllegalArgumentException e) {
    throw new IllegalArgumentException("Invalid XPath expression: " + xpathStr, e);
}

Prevention

When it happens

Trigger: Calling new Xpath2Selector(str) or Xpath2Selector.newInstance(str) with a malformed expression: unbalanced parentheses/brackets, invalid axis or function names, XPath 3.0-only syntax, stray characters, or empty string.

Common situations: Copying XPath written for HTMLCleaner/jsoup/XPath 1.0 syntax that Saxon rejects; typos like '//div[@class="x"' with missing bracket; using functions unsupported in XPath 2.0; constructing selectors dynamically from user input.

Related errors


AI-assisted analysis of code4craft/webmagic@67816a19d6 (2026-09-08). Data as JSON: /api/errors/9c07cea292303d4a. Report an issue: GitHub.

Appendix: source

Thrown at webmagic-saxon/src/main/java/us/codecraft/webmagic/selector/Xpath2Selector.java:48

 *
 * @author code4crafter@gmail.com, hooy <br>
 * Date: 13-4-21
 * Time: 上午9:39
 */
public class Xpath2Selector implements Selector, NodeSelector {

    private final String xpathStr;

    private XPathExpression xPathExpression;

    private final Logger logger = LoggerFactory.getLogger(getClass());

    public Xpath2Selector(String xpathStr) {
        this.xpathStr = xpathStr;
        try {
            init();
        } catch (XPathExpressionException e) {
            throw new IllegalArgumentException("XPath error!", e);
        }
    }

    public static Xpath2Selector newInstance(String xpathStr) {
        return new Xpath2Selector(xpathStr);
    }

    enum XPath2NamespaceContext implements NamespaceContext {

        INSTANCE;

        private final Map<String, String> prefix2NamespaceMap = new ConcurrentHashMap<>();

        private final Map<String, List<String>> namespace2PrefixMap = new ConcurrentHashMap<>();

        private void put(String prefix, String namespaceURI) {
            prefix2NamespaceMap.put(prefix, namespaceURI);
            List<String> prefixes = namespace2PrefixMap.computeIfAbsent(namespaceURI, k -> new ArrayList<>());

View on GitHub (pinned to 67816a19d6)