如何在 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 作为值...但是有很多方法可以做到这一点...
我想一次加载所有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 作为值...但是有很多方法可以做到这一点...