You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Saxon HE 12.7中XPath语法错误位置不准及异常处理疑问

关于Saxon HE 12.7 XPath语法错误位置不准确的问题

在使用Saxon HE 12.7时,遇到无法获取XPath语法错误准确位置信息的问题。以下是复现问题的示例代码:

import java.io.*;
import net.sf.saxon.*;
import net.sf.saxon.s9api.*;

public class SaxonXPathTest {
  public static final void main(
      String[] args
  ) throws Exception {
    // Following expression should generate an error
    String expression = "/dmAddress/\ndmIdent/\ndmCode/\n@modelIdentCode[";
    Processor proc = new net.sf.saxon.s9api.Processor(new Configuration());
    XPathCompiler compiler = proc.newXPathCompiler();
    printExpression(expression);
    try {
      compiler.compilePattern(expression);
    } catch (Exception e) {
      System.out.println(formatSaxonExceptionMessage(e));
    }
  }

  static void printExpression(
      String text
  ) throws Exception
  {
    BufferedReader in = new BufferedReader(new StringReader(text));
    String line = null;
    int n = 1;
    while ((line = in.readLine()) != null) {
      System.out.print(n+":\t");
      System.out.println(line);
      ++n;
    }
  }

  static String formatSaxonExceptionMessage(
      Throwable e
  ) {
    net.sf.saxon.trans.XPathException xpe =
      getSaxonXPathException(e);
    if (xpe == null) {
      return e.getLocalizedMessage();
    }
    String message = xpe.getLocalizedMessage();
    Location loc = xpe.getLocator();
    if (loc == null) {
      return message;
    }
    int line = loc.getLineNumber();
    int col = loc.getColumnNumber();
    if ((line < 0) && (col < 0)) {
      return message;
    }
    // XXX: Line can be negative even if column is not!!
    return "Error at "+line+':'+col+": "+message;
  }

  static net.sf.saxon.trans.XPathException getSaxonXPathException(
      Throwable e
  ) {
    if (e == null) return null;
    if (e instanceof net.sf.saxon.trans.XPathException) {
      return (net.sf.saxon.trans.XPathException)e;
    }
    return getSaxonXPathException(e.getCause());
  }
}

程序执行后输出如下:

1:      /dmAddress/
2:      dmIdent/
3:      dmCode/
4:      @modelIdentCode[
Error at 2:17: Expected an expression, but reached the end of the input

实际错误行应为第4行,但返回的错误位置是第2行。请问:

  1. 是否遗漏了什么配置?
  2. 由于主异常实例并非XPathException,是否必须遍历异常栈才能获取关联的Location实例?

问题解答

1. 错误位置不准确的原因及解决方法

该问题源于Saxon对XPath模式(Pattern)的解析逻辑。compilePattern处理的是模式语法,而非完整XPath表达式语法。在解析多行模式时,词法分析器会将换行符视为分隔符,导致位置计算出现偏移。

解决方案:

  • 若无需严格使用模式,改用compile方法编译完整XPath表达式,能获得更准确的错误位置。
  • 若必须使用模式,可将表达式合并为单行,或通过配置启用精确位置跟踪:
    Configuration config = new Configuration();
    config.setLineNumbering(true);
    Processor proc = new Processor(config);
    
    注意:Saxon HE版本中部分高级位置跟踪功能可能受限,优先推荐改用compile方法。

2. 异常处理的问题

是的,s9api接口中compilePattern抛出的顶层异常为SaxonApiException,XPathException被包装在其getCause()中。因此必须通过遍历异常栈(或直接调用getCause())才能获取包含位置信息的XPathException实例。你当前实现的getSaxonXPathException方法逻辑正确,无需修改。

内容的提问来源于stack exchange,提问作者ewh.eps

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 01:44:54