RE: большой XML-файл - PullRequest
       13

RE: большой XML-файл

5 голосов
/ 03 февраля 2009

Следующий вопрос к Большому XML-файлу :

Сначала большое спасибо за ваши ответы. После ... что я делаю не так? Это мой класс, который использует SAX:

public class SAXParserXML extends DefaultHandler {
  public static void ParcourXML() {

      DefaultHandler handler = new SAXParserXML();
      SAXParserFactory factory = SAXParserFactory.newInstance();
      try {
          String URI = "dblp.xml";
          SAXParser saxParser = factory.newSAXParser();
          saxParser.parse(URI,handler);
      } catch (Throwable t) {
     t.printStackTrace ();
       }
  }



  public void startElement (String namespaceURI,String simpleName,String qualifiedName,Attributes attrs) throws SAXException {
  }
  public void endElement (String namespaceURI,String simpleName,String qualifiedName) throws SAXException {

  }
}

Вы видите, что я ничего не делаю с моим XML-файлом, но он выдает эту ошибку:

java.lang.OutOfMemoryError: Java heap space
    at com.sun.org.apache.xerces.internal.util.XMLStringBuffer.append(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.refresh(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.invokeListeners(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.peekChar(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
    at javax.xml.parsers.SAXParser.parse(Unknown Source)
    at javax.xml.parsers.SAXParser.parse(Unknown Source)
    at SAXParserXML.ParcourXML(SAXParserXML.java:30)
    at Main.main(Main.java:28)

Я пробовал также Stax ... та же ошибка ... что я могу сделать? Также я увеличил размер кучи Java до 1260M

java -Xmx1260M SAXParserXML

Файл XML имеет такую ​​форму:

<dblp> 
   <incollection> 
      <author>... </author> 
      .... 
      <author>... </author> 
      #other tags-i'm interested only by <author>#
      ... 
   </incollection> 
   <incollection> 
   # the same thing# 
   </incollection> 
   .... 
</dblp> 

Вы можете найти оригинальный файл: http://dblp.uni -trier.de / xml /

Спасибо

Ответы [ 5 ]

6 голосов
/ 04 февраля 2009

Есть ошибка для Java 1.6, которая показывает ту же самую трассировку стека, и она не исправлена ​​на данный момент. Новые версии Xerces кажутся хорошими.

Для таких больших документов, которые все еще содержат достаточное количество структур, вы можете подумать об использовании разборки извлечения, то есть разбора частичных структур, например с StAX .

2 голосов
/ 04 февраля 2009

Ну, учитывая:

public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String argv[]) {
        Writer out;

        // Use an instance of ourselves as the SAX event handler
        Echo handler = new Echo();
        // Use the default (non-validating) parser
        SAXParserFactory factory = SAXParserFactory.newInstance();
        try {
            // Set up output stream
            out = new OutputStreamWriter(System.out, "UTF8");
            // Parse the input 
            SAXParser saxParser = factory.newSAXParser();
            saxParser.parse(new File("/tmp/dblp.xml"), handler);
        } catch (Throwable t) {
            t.printStackTrace();
        }
        System.out.println("Incollections = " + handler.cnt);
        System.exit(0);
    }

    static class Echo extends DefaultHandler {
        public int cnt = 0;
        @Override
        public void startElement(String namespaceURI,
                String sName, // simple name
                String qName, // qualified name
                Attributes attrs)
                throws SAXException {
            if (qName.equals("incollection")) {
                cnt = cnt + 1;
            }
        }
    }
}

Это работает для меня под Java 5, но я получаю OOM под Java 6.

Я запускаю это так:

java -DentityExpansLimit=512000 -jar xmltest.jar

И это печатает:

Incollections = 8353

Что удобно:

grep "<incollection" /tmp/dblp.xml | wc -l
8353

Итак, к вашему сведению, точка данных и т. Д.

0 голосов
/ 31 марта 2009

Похоже, что один из текстовых сегментов (или CDATA, инструкция обработки или комментарий) в файле XML очень длинный, и анализатор не разбивает его на несколько сегментов. Или же это может быть из-за того, что синтаксический анализатор не может правильно проанализировать объявление DOCTYPE: если это так, он может попытаться прочитать все содержимое XML, как если бы он был частью подмножества DTD.

Но это только предположение. Вы упомянули, что пробовали Stax: какая реализация? JDK 1.6 поставляется с Sun Sjsxp. Но вы также можете попробовать Woodstox (http://woodstox.codehaus.org),, который часто обрабатывает вещи более надежно). Так что, если вы не используете Woodstox, вы можете увидеть, что произойдет. Он разбивает текстовые сегменты на более мелкие куски, если вы не принудительно объединили текст (не по умолчанию).

Да, и на всякий случай, когда вы тестировали с использованием эталонной реализации Stax (http://stax.codehaus.org);, к сожалению, известно, что она очень глючная. Это может вызвать проблемы. И Sjsxp, и Woodstox - намного лучший выбор для Stax.

0 голосов
/ 04 февраля 2009

Я не знаю правильной терминологии для этого, но насколько глубока ваша XML? Например, тег "author" в вашем примере имеет глубину 2 элемента. Если у вас действительно очень глубокие теги, может, поэтому у вас проблемы с памятью?

0 голосов
/ 04 февраля 2009

В вашем коде, похоже, есть проблема с объектами HTML, а именно "Jos &eacute;" в первом блоке. По крайней мере, мой браузер сообщает мне, что с ним возникает проблема, когда я открываю файл, и в трассировке стека появляется XMLEntityScanner Я не эксперт по XML, но может ли быть так, что сущности HTML на самом деле не определены для XML вообще?

Редактировать Да, вот и все. Согласно Википедии сущности, подобные &eacute;, определены в HTML DTD; XML имеет очень небольшое количество предопределенных сущностей.

...