如何在VTD-xml Parser中实现CachedExpr

时间:2016-10-31 10:43:07

标签: vtd-xml

我想立即加载CachedExpr中的所有XPath和变量并多次使用它。任何人都可以提供在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类,它正在成功解析。我们在CachedExpr中编译xpath列表并重新使用它而不是每次编译。

1 个答案:

答案 0 :(得分:0)

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

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

考虑以下表达式:

// a [text()= // b]

对于// a的每个评估,你需要评估谓词[text()= // b] ...所以缓存表达式将保存// b的结果并将其重用于后续谓词评估。

如果你的目标是坚持预先编译的XPath表达式...我的建议是使用哈希映射(或表)你可以使用xpath字符串作为键和autoPilot作为值...但是有很多方法可以做此...