2016-10-31 3 views
1

CachedExpr의 모든 XPath와 변수를 한 번에로드하여 여러 번 사용하려고합니다. 누구나 CachedExpr에서 변수와 XPath를 추가 할 수있는 샘플을 제공 할 수 있으며 XPathNamespace를 선언하는 방법을 알려줍니다.VTD-xml 파서에 CachedExpr을 구현하는 방법

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 목록을 컴파일하고 매번 컴파일하는 대신 재사용합니다.

+0

CachedExpr은 사용자가 직접 상호 작용하는 것으로 생각하지 않습니다 ... 일단 켜져 있으면 (기본적으로) 사용자가 기본적으로 지정한대로 작동합니다 ... XPathNamespace는 AutoPilot으로 선언됩니다 ... 일반 xpath 평가와 같습니다 ... –

답변

0

난 당신이 캐시 된 표현의 목적을 오해 할 수있다 생각 ... cachedExpr의 목표는 이후 재사용을위한 메모리에 XPath를 컴파일 지속 하지 ...

의 목적은의 출력을 캐시입니다 이전에 XPath 평가 결과 (일반적으로 절대 표현식)가 여러 번 필요하지만 각 재평가를 위해 낭비하지 않으려는 경우

는 다음 식을 고려하십시오

// A [텍스트를() = // B] 술어 [텍스트를 평가해야합니다 // (A)의 모든 평가

() = // b] ... 캐시 표현식이 // b 결과를 저장하고 후속 술어 평가를 위해 다시 사용합니다 ...

사전 컴파일 된 XPath 표현을 유지하는 것이 목표라면 ... 내 제안은 해시지도 (또는 테이블) xpath 문자열을 키로 사용하고 autoPilot을 값으로 사용할 수는 있지만 ... 이렇게하려면 여러 가지 방법이 있습니다.

+0

우리는 xpath를 구문 분석하는 성능을 향상시키기 위해 노력하고 있습니다. 실제 파일을 디스크에 기록하는 대신 인덱스를 생성하거나로드 할 수있는 다른 방법이 있습니까? – zulu

+0

작은 xml 파일을 처리하거나 루핑하는 경우에만 xpath를 구문 분석하는 성능이 중요합니다 ... 항상 xpath를 사전 처리 컴파일 ... 루프에 넣지 마십시오 ... 사전 컴파일 및 재사용 (예 : autoPilot.resetXPath() 호출) .. .. –

+0

색인 만들기 및로드는 항상 VTD의 지속성 측면을 참조합니다 ... 즉, 항상 읽기 및 디스크 (HD 또는 플래시) 쓰기 ... 파싱의 출력을 가비지 수집하지 않으면 이것은 RAM 공간을 차지할 것이라는 것을 의미합니다 ... 처음부터 말하는 인덱스는 없습니다. –