2017-05-09 44 views
0

我使用XPATH在我的項目,我需要通過節點來遍歷有條件條件的XPath使用預編譯的XPath

public static String getNodeContentForMultipleTag1(XPathExpression expr,Document doc) { 
    try { 

     NodeList typeResult = (NodeList) expr.evaluate(doc, XPathConstants.NODESET); 
     for (int i = 0; i < typeResult.getLength(); i++) { 
      Node typeResultNode = typeResult.item(i); 
      System.out.println(typeResultNode.getTextContent()); 
     } 
    } catch (XPathExpressionException e) { 
     throw new RuntimeException("Failed parsing expression",e); 
    } 
    return null; 
} 

public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, XPathExpressionException { 
    String s="<ex><DtTm><TxDtTm><Cd>ABCD</Cd><dt>1234</dt></TxDtTm><TxDtTm><Cd>XYZ</Cd><dt>891</dt></TxDtTm></DtTm></ex>"; 
    InputStream inputStream = new ByteArrayInputStream(s.getBytes(StandardCharsets.UTF_8)); 
    DocumentBuilder db= XpathInstanceUtil.getDocumentBuilderFactory().newDocumentBuilder(); 
    Document doc = db.parse(inputStream); 
    XPath xpath = XpathInstanceUtil.getXPathFactory().newXPath(); 
    XPathExpression expr = xpath.compile("/ex/DtTm/TxDtTm"); 
    inputStream.close(); 
    long st = System.currentTimeMillis(); 
    getNodeContentForMultipleTag1(expr, doc); 
    long end = System.currentTimeMillis(); 
    System.out.println(end-st); 

    long st1 = System.currentTimeMillis(); 
    getNodeContentForMultipleTag1(expr, doc); 
    long end1 = System.currentTimeMillis(); 
    System.out.println(end1-st1); 

} 

如果Cd值是ABCD我應該得到1234作爲結果。 我曾嘗試以下

public static String getNodeContentForMultipleTag(String expresssion,String expectedNode,String expectedExpressionTag,Document doc) { 
    try { 
     XPath xpath = XpathInstanceUtil.getXPathFactory().newXPath(); 
     NodeList typeResult = (NodeList) evaluateXPath(doc,expresssion,xpath,XPathConstants.NODESET); 
     NodeList valueResult= (NodeList) evaluateXPath(doc,expectedExpressionTag,xpath,XPathConstants.NODESET); 
     //NodeList typeResult = (NodeList) xpath.evaluate(expresssion,doc, XPathConstants.NODESET); 
     //NodeList valueResult = (NodeList) xpath.evaluate(expectedExpressionTag,doc, XPathConstants.NODESET); 
     for (int i = 0; i < typeResult.getLength(); i++) { 
      Node typeResultNode = typeResult.item(i); 
      typeResultNode.getParentNode().removeChild(typeResultNode); 
      Node valueResultNode = valueResult.item(i); 
      if(typeResultNode.getTextContent().equals(expectedNode) && valueResultNode!=null){ 
       valueResultNode.getParentNode().removeChild(valueResultNode); 
       return valueResultNode.getTextContent(); 
      } 
     } 
    } catch (XPathExpressionException e) { 
     throw new RuntimeException("Failed parsing expression"+expresssion,e); 
    } 
    return null; 
} 

這是表達什麼樣子

public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException { 
     String s="<ex><DtTm><TxDtTm><Cd>ABCD</Cd><dt>1234</dt></TxDtTm><TxDtTm><Cd>XYZ</Cd><dt>891</dt></TxDtTm></DtTm></ex>"; 
     InputStream inputStream = new ByteArrayInputStream(s.getBytes(StandardCharsets.UTF_8)); 
     DocumentBuilder db= XpathInstanceUtil.getDocumentBuilderFactory().newDocumentBuilder(); 
     Document doc = db.parse(inputStream); 
     String ss = getNodeContentForMultipleTag("/ex/DtTm/TxDtTm/Cd", "XYZ", "/ex/DtTm/TxDtTm/dt", doc); 
     System.out.println(ss); 
    } 

但其性能非常low.How應該改爲解析有效

+0

性能取決於您使用的產品,但您向我們展示的代碼將使用任何實現Java XPath API的產品運行。性能還取決於您使用的Java版本。您還應該量化您需要的性能和您實際獲得的性能,以便我們可以評估所需更改的劇烈程度。 –

+0

是的,我嘗試了java xpath.Actually我的xml看起來比posted.There有巨大的性能影響,因爲xpath.I不重複使用表達式。所以我必須評估超過1000次的一個XML,它會產生大量的Xobject – pppavan

+0

使用xpath我能夠在7分鐘內解析200000並消耗大量內存 – pppavan

回答

1

此代碼似乎完全離奇。爲什麼在Java中而不是在XPath中完成所有這些工作?爲什麼在搜索時修改DOM樹?

你只需要執行XPath表達式/ex/DtTm/TxDtTm[Cd='ABCD']/dt,你就在那裏。

+0

感謝您的回覆。我如何使Cd值參數化? – pppavan

+0

將一個變量放入XPath表達式'[Cd = $ p1]'中,然後使用'xpath.setXPathVariableResolver(....)'綁定'$ p1'的值。 –