2017-01-09 3 views
0

У меня есть пример XMLбыстро извлечения данных из XML

<?xml version="1.0" encoding="UTF-8"?> 
    <tag_1> 
    <tag_2>A</tag_2> 
    <tag_3>B</tag_3> 
    <tag_4>C</tag_4> 
    <tag_5>D</tag_5> 
    </tag_1> 
</xml> 

Теперь я заинтересован, чтобы извлечь только определенные данные.

Например

tag_1/tag_5 -> D 

tag_1/tag_5 мое определение данных (только данные, которые я хочу), которая носит динамический характер, что означает, что завтра tag_1/TAG_4 будет мое определение данных.

Так что на самом деле мой xml - это большой набор данных. И эти xml полезные нагрузки идут как 50 000/час до 80 000/час.

Я хотел бы знать, есть ли уже высокопроизводительный инструмент чтения XML-документов или какая-то специальная логика, которую я могу реализовать, которая извлекает данные в зависимости от определения данных.

В настоящее время у меня есть реализация с использованием парсера Stax, но это занимает почти день, чтобы разобрать 80 000 xml.

public class VTDParser { 

    private final Logger LOG = LoggerFactory.getLogger(VTDParser.class); 

    private final VTDGen vg; 

    public VTDParser() { 
     vg = new VTDGen(); 
    } 

    public String parse(final String data, final String xpath) { 
     vg.setDoc(data.getBytes()); 
     try { 
      vg.parse(true); 
     } catch (final ParseException e) { 
      LOG.error(e.toString()); 
     } 

     final VTDNav vn = vg.getNav(); 
     final AutoPilot ap = new AutoPilot(vn); 
     try { 
      ap.selectXPath(xpath); 
     } catch (final XPathParseException e) { 
      LOG.error(e.toString()); 
     } 

     try { 
      while (ap.evalXPath() != -1) { 
       final int val = vn.getText(); 
       if (val != -1) { 
        return vn.toNormalizedString(val); 
       } 
      } 
     } catch (XPathEvalException | NavException e) { 
      LOG.error(e.toString()); 
     } 
     return null; 
    } 
} 
+0

Не знаю, почему я получил -1. Я не понятен? Я просто ищу идеи и не прошу кого-то реализовать меня. –

+0

50-80 000/час, что соответствует 20 секундам. Если вы работаете только однопоточно, это означает 1/20 секунды для одного xml. Если файлы xml очень велики, как вы говорите, вы никогда не сможете проанализировать его в течение 0.05 секунд, тем более, что они могут быть другими накладными расходами, которые вы, вероятно, не можете контролировать (например, время ожидания сети/диска при чтении xml-файлов). Чтобы достичь своей цели, вам сначала нужно распараллелить работу. И тогда, вероятно, подумайте о том, чтобы помещать данные в базу данных для упрощения запросов, поэтому вам не нужно повторно анализировать все документы, когда завтра ваш запрос изменится. Но база данных также нуждается в планировании – cello

+0

Да, сэр. Фактически я реализовал, наконец, использование Vtd-Xml. Я также хочу услышать ваш ответ. –

ответ

0

Это мой мод для вашего кода, который компилирует xpath один раз и повторно используется много раз. Он компилирует xpath без привязки к экземпляру VTDNav. Он также вызывает resetXPath перед выходом из метода parse. Я, однако, не показал вам, как предварительно проиндексировать документы xml с помощью VTD ..., чтобы избежать повторного разбора .... и я подозреваю, что это может быть создатель различий для вашего проект ... Вот справочный документ о возможностях ВТД-XML ..

http://recipp.ipp.pt/bitstream/10400.22/1847/1/ART_BrunoOliveira_2013.pdf

import com.ximpleware.*; 


public class VTDParser { 
     // private final Logger LOG = LoggerFactory.getLogger(VTDParser.class); 

     private final VTDGen vg; 
     private final AutoPilot ap; 
     public VTDParser() throws VTDException{ 
      vg = new VTDGen(); 
      ap = new AutoPilot(); 
      ap.selectXPath("https://stackoverflow.com/a/b/c");// this is how you compile xpath w/o binding to an XML doc 
     } 

     public String parse(final String data, final AutoPilot ap1) { 
      vg.setDoc(data.getBytes()); 
      try { 
       vg.parse(true); 
      } catch (final ParseException e) { 
       LOG.error(e.toString()); 
      } 

      final VTDNav vn = vg.getNav(); 
      ap1.bind(vn); 
      try { 
       while (ap.evalXPath() != -1) { 
        final int val = vn.getText(); 
        if (val != -1) { 
         return vn.toNormalizedString(val); 
        } 
       } 
      } catch (XPathEvalException | NavException e) { 
       LOG.error(e.toString()); 
      } 
      ap.resetXPath();// reset your xpath here 
      return null; 
     } 
} 
+0

Спасибо. Я не понял, почему мы передали AutoPilot ap1 в качестве параметра для синтаксического анализа и называли bind (vn) –

+0

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

+0

добавлена ​​ссылка на файл vtd-xml –

Смежные вопросы