如何在 VTD-xml Parser 中实现 CachedExpr

How to implement CachedExpr in VTD-xml Parser

我想一次加载所有XPath 和CachedExpr 中的变量并多次使用它。谁能提供在 CachedExpr 中添加变量和 XPath 的示例,并让我知道如何在其中声明 XPathNamespace。

public class VTDParser {
private final CustomAutoPilot autoPilot;

public static class CustomAutoPilot extends com.ximpleware.AutoPilot {
    final Hashtable<String, com.ximpleware.Expr> variables = new Hashtable<>();

    public CustomAutoPilot() {
        super();
    }

    public CustomAutoPilot(VTDNav v) {
        super(v);
    }

    public void declareVariableExpr(String varName, String varExpr) throws XPathParseException {
        try {
            parser p = new parser(new StringReader(varExpr));
            p.nsHash = nsHash;
            p.symbolHash = variables;
            xpe = (com.ximpleware.Expr) p.parse().value;
            variables.put(varName, xpe);
            ft = true;
        } catch ( XPathParseException e ) {
            throw e;
        } catch ( Exception e ) {
            throw new XPathParseException("Error occurred");
        }
    }

    @Override
    public void selectXPath(String s) throws XPathParseException {
        try {
            parser p = new parser(new StringReader(s));
            p.nsHash = nsHash;
            p.symbolHash = variables;
            xpe = (com.ximpleware.Expr) p.parse().value;
            ft = true;
            if ( enableCaching )
                xpe.markCacheable();
        } catch ( XPathParseException e ) {
            throw e;
        } catch ( Exception e ) {
            throw new XPathParseException("");
        }
    }

    public VTDNav getNavigationObject() {
        return vn;
    }
}

public VTDParser(String message) throws ParseException {
    try {
        VTDGen vg = new VTDGen();
        byte[] content = message.getBytes(Charset.defaultCharset());
        vg.setDoc(content);
        vg.parse(true);
        VTDNav vn = vg.getNav();
        autoPilot = new CustomAutoPilot(vn);
        autoPilot.declareXPathNameSpace("prefix", "http://www.w3.org");
    } catch ( ParseException e ) {
        throw e;
    }
}

public String asString(String xpath) throws XPathParseException {
    try {
        autoPilot.selectXPath(xpath);
        return autoPilot.evalXPathToString().trim();
    } catch ( XPathParseException e ) {
        throw e;
    }
}

public void variable(String name, String value) throws XPathParseException {
    try {
        autoPilot.declareVariableExpr(name, value);
    } catch ( XPathParseException e ) {
        throw e;
    }
}

public static void main(String[] args) throws ParseException, XPathParseException {
    String xml = "<tree><fruit> Mango</fruit></tree>";
    VTDParser parser = new VTDParser(xml);
    System.out.println(parser.asString("//tree/fruit"));
}

}

我们已经编写了 CustomAutopilot class,它正在解析成功。 WE ant o 编译 CachedExpr 中的 xpath 列表并重用它,而不是每次都编译。

我认为您可能误解了缓存表达式的用途...cachedExpr 的目标是而不是将已编译的 XPath 保留在内存中以供后续重用...

它的目的是在多次需要这些结果时缓存先前评估的 XPath 评估结果(通常是那些绝对表达式)的输出,但您不想为每次重新评估浪费周期。

考虑以下表达式:

//a[文本()=//b]

对于 //a 的每个评估,您都需要评估谓词 [text()=//b]... 那么什么缓存表达式将保存 //b 的结果并将其重新用于后续谓词评估...

如果您的目标是保留预编译的 XPath 表达式...我的建议是使用散列映射(或 table),您可以使用 xpath 字符串作为键并使用 autoPilot 作为值...但是有很多方法可以做到这一点...