2012-04-22 6 views
1

クラスが今見るには、JavaでXPathを経由してXML文書を解析するための古典的なアプローチである:のXpathアプローチ大きなファイルの場合には、あなたがつもりだ

そこで
public class Main { 

    private Document createXMLDocument(String fileName) throws Exception { 
     DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); 
     domFactory.setNamespaceAware(true); 
     DocumentBuilder builder = domFactory.newDocumentBuilder(); 
     Document doc = builder.parse(fileName); 

     return doc; 
    } 

    private NodeList readXMLNodes(Document doc, String xpathExpression) throws Exception { 
     XPath xpath = XPathFactory.newInstance().newXPath(); 
     XPathExpression expr = xpath.compile(xpathExpression); 

     Object result = expr.evaluate(doc, XPathConstants.NODESET); 
     NodeList nodes = (NodeList) result; 

     return nodes; 
    } 

    public static void main(String[] args) throws Exception { 
     Main m = new Main(); 
     Document doc = m.createXMLDocument("tv.xml"); 
     NodeList nodes = m.readXMLNodes(doc, "//serie/eason/@id"); 
     int n = nodes.getLength(); 

     Map<Integer, List<String>> series = new HashMap<Integer, List<String>>(); 

     for (int i = 1; i <= n; i++) { 
      nodes = m.readXMLNodes(doc, "//serie/eason[@id='" + i + "']/episode/text()"); 
      List<String> episodes = new ArrayList<String>(); 
      for (int j = 0; j < nodes.getLength(); j++) { 
       episodes.add(nodes.item(j).getNodeValue()); 
      } 
      series.put(i, episodes); 
     } 

     for (Map.Entry<Integer, List<String>> entry : series.entrySet()) { 
      System.out.println("Season: " + entry.getKey()); 
      for (String ep : entry.getValue()) { 
       System.out.println("Episodio: " + ep); 
      } 
      System.out.println("+------------------------------------+"); 
     } 
    } 
} 

私はいくつかの方法がで心配されるように見つけます巨大なXMLファイルの場合。私が対処する必要があるXMLドキュメントが顧客によって作成されるため

Document doc = builder.parse(fileName); 

return doc; 

または

Object result = expr.evaluate(doc, XPathConstants.NODESET); 
    NodeList nodes = (NodeList) result; 

    return nodes; 

の使用と同じように、私は心配していると、あなたの内側に基本的に電子メールを記述するレコードの不特定多数を持つことができ、その内容(すべてのユーザーは自分の個人的な電子メールを持っているので、そこにはたくさんのHTMLがあります)。私はそれが賢明なアプローチではないことを知っていますが、それは可能性の一つであり、私がここに到着する前に既に稼働していました。

私の質問は:parseevaluate xpathを使用している巨大なxmlファイルはどうすればいいですか?

+0

XML解析にはどのライブラリを使用していますか?あなたはスタックスパーサーを見たいと思うかもしれません –

+0

私は何も決定していません...それが私が求めている理由です。 – dierre

+0

スタックスは良い考えです。 DOMとは対照的に、シリアルパーサーであるため、大きなファイルは処理に必要なメモリが少なくなります。 –

答えて

2

です。まず、XPathはXMLを解析しません。 createXMLDocument()メソッドはそれを行い、解析されたXMLのツリー表現を出力として生成します。次にXPathを使用してツリー表現を検索します。

あなたが本当に探しているのは、解析中のXMLをオンザフライで検索するものです。

これを行う1つの方法は、「文書投影」(たとえば、Saxon-EE)を実装するXQueryシステムです。これにより、クエリを分析してドキュメントのどの部分が必要であるかを確認し、ドキュメントを解析すると、実際に必要とされるドキュメントの部分だけを含むツリーが構築されます。

しかし、クエリが例のものと同じように単純な場合、startElementやendElementなどのイベントがアプリケーションにXMLパーサーによって通知されるSAXアプリケーションとしてコーディングするのは難しくありませんメモリにツリーを構築することなく。

+0

スキーマはかなりシンプルです。問題は、ある時点で/ delivery/recipients/new_recipientのようなものを問い合わせるということです。私はnew_recipientsのshitloadを持っているでしょう、いくつかの顧客は3GBのサイズの300kの受信者のような何かを持っています。私は特定のクエリを要求することができますが、ストリームのように読むことで、メモリの過負荷を制御できるシステムが欲しいです。 – dierre

関連する問題