0

それぞれが最大 500 MB の大きな xml ファイルから読み取る必要があります。バッチは通常、実行ごとに 500 個のそのようなファイルを処理します。そこからテキスト ノードを抽出すると同時に、そこから xml ノードを抽出する必要があります。使いやすいようにJavaでxpath DOMを使用しましたが、リソースが限られているため、メモリの問題により機能しません。

現在、Java で SAX または Stax を使用するつもりです。テキスト ノードは簡単に抽出できますが、sax を使用して xml から xml ノードを抽出する方法がわかりません。

サンプル:

<?xml version="1.0"?>
<Library>
  <Book name = "ABC">
    <Author>John</Author>
    <PrintingCompanyDT><Printer>Sam</Printer><Printmachine>Laser</Printmachine>    
    <AssocPrint>Oreilly</AssocPrint> </PrintingCompanyDT>
  </Book>
  <Book name = "123">
    <Author>Mason</Author>
    <PrintingCompanyDTv<Printervkelly</Printer><Printmachine>DOTPrint</Printmachine>
    <AssocPrint>Oxford</AssocPrint> </PrintingCompanyDT>
  </Book>
</Library>

期待される結果: 1)本: ABC:
著者:John
PrintCompany Detail XML:

<PrintingCompanyDT>
  <Printer>Sam</Printer>
  <Printmachine>Laser</Printmachine>
  <AssocPrint>Oreilly</AssocPrint> 
</PrintingCompanyDT>


2) 本: 123
著者: Mason
PrintCompany 詳細 XML:

<PrintingCompanyDT>
  <Printer>kelly</Printer>
  <Printmachine>DOTPrint</Printmachine>
  <AssocPrint>Oxford</AssocPrint>
</PrintingCompanyDT>


public void characters(char ch[], int start, int length) メソッドで通常の方法で文字を追加しようとすると、次のようになります
1)Book: ABC:
Author:John
PrintCompany Detail XML :

Sam 
  Laser
      Oreilly

正確にコンテンツとスペース。

javaのSAXまたはStaXパーサーを介してxmlファイルからそのままxmlノードを抽出する方法を誰かが提案できますか?

4

1 に答える 1

0

この種のタスクには、SAX や StAX を直接使用するのではなく、XOMを使用したくなるでしょう。XOM は DOM や JDOM に似たツリーベースの表現ですが、一種のセミストリーミング方式で XML の「小枝」を処理することをサポートしています。別。また、すべてNodeにはtoXML、ノードを XML として出力するメソッドがあります。

import nu.xom.*;

public class LibraryProcessor extends NodeFactory {
  private Nodes empty = new Nodes();
  private bookNum = 0;

  /** Called for each closing tag in the XML */
  public Nodes finishMakingElement(Element element) {
    if("Book".equals(element.getLocalName())) {
      bookNum++;
      // process the complete Book element ...
      processBook(element);
      // ... and throw it away
      return empty;
    } else {
      // process other elements (except Book) in the normal way
      return super.finishMakingElement(element);
    }
  }

  private void processBook(Element book) {
    System.out.println(bookNum + ": " +
        book.getAttributeValue("name"));
    System.out.println("Author: " +
        book.getFirstChildElement("Author").getValue());
    System.out.println("PrintCompany Detail XML: " +
        book.getFirstChildElement("PrintingCompanyDT").toXML());
  }

  public static void main(String[] args) throws Exception {
    Builder builder = new Builder(new LibraryProcessor());
    builder.build(new File(args[0]));
  }
}

processBookこれは、各Book要素に対して 1 回ずつ順番に呼び出して、XML ドキュメント全体を処理します。内部では、 XOMノードとして XML ツリーprocessBook全体にアクセスできますがBook、ファイル全体を一度にメモリにロードする必要はありません。XOM チュートリアルの「ファクトリ、フィルター、サブクラス化、およびストリーミング」セクションに、この手法の詳細が記載されています。

この例は、XOM API の最も基本的なビットを示しているだけですが、より複雑な処理を行う必要がある場合は、強力な XPath サポートも提供します。たとえば、次を使用してPrintMachine要素に直接アクセスできますprocessBook

Element machine = (Element)book.query("PrintingCompanyDT/PrintMachine").get(0);

または、構造がそれほど規則的でない場合、たとえば、PrintingCompanyDTが直接の子であるBook場合と、より深い場合(孫など)の場合は、次のようなクエリを使用できます

Element printingCompanyDT = (Element)book.query(".//PrintingCompanyDT").get(0);

(直接の子のみを検索//するのではなく、任意のレベルで子孫を検索するための XPath 表記です)。/

于 2012-07-17T22:53:32.487 に答える