Ленивый синтаксический анализ элементов в огромном XML

#xml #scala #xml-parsing #scales-xml

#xml #scala #xml-синтаксический анализ #масштабирование-xml

Вопрос:

Мы обрабатываем файлы OTDS. В двух словах, это XML-файлы, которые содержат много данных и могут иметь более 15 ГБ.

Мы выбрали библиотеку scalesXml для эффективной обработки этих файлов.

Позвольте мне показать вам пример:

 <?xml version="1.0" encoding="UTF-8"?>
<Otds UpdateMode="Merge"
xmlns="http://otds-group.org/otds"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
Version="1.9.1" xsi:schemaLocation="http://otds-group.org/otds ../xsd/otds.xsd">
 <Brands>
     ...
 </Brands>
 <Accommodations>
  <Accommodation Key="A">
   ...
   <SellingAccom>
    ...
    <PriceItems Key="1">...</PriceItems>
    ...
   </SellingAccom>
   ...
  </Accommodation>

...  <!-- A lot of <Accomodation> tags -->

  <Accommodation Key="Z">
  ...
  </Accommodation>
  <PriceItems Key="Global1"></PriceItems>   <!-- Collect all of these     -->
  <PriceItems Key="Global2"></PriceItems>
 </Accommodations>
</Otds>
  

Мы столкнулись с проблемой. XML содержит много тяжелых <Accomodation> тегов. Мы бы извлекли все <PriceItems> , которые являются прямыми дочерними элементами <Accommodations> тега.

Я создал настоящий упрощенный файл :

 <?xml version="1.0" encoding="UTF-8"?>
<Otds UpdateMode="Merge"
xmlns="http://otds-group.org/otds"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
Version="1.9.1" xsi:schemaLocation="http://otds-group.org/otds ../xsd/otds.xsd">
 <Brands>
  <Brand>EBIWA</Brand>
 </Brands>
 <Accommodations>
  <Accommodation Key="ATH432">
   <SellingAccom>
    <PriceItems Key="1"></PriceItems>
   </SellingAccom>
  </Accommodation>
  <Accommodation Key="ATH433">
   <SellingAccom>
    <PriceItems Key="2"></PriceItems>
   </SellingAccom>
  </Accommodation>
  <PriceItems Key="Global"></PriceItems>
 </Accommodations>
</Otds>
  

Мой текущий подход :

  1. Он возвращает итератор [PriceItems] для всех PriceItems, а не только для последнего, который ожидается

     val ns = Namespace("http://otds-group.org/otds")
    val Otds = ns("Otds")
    val Accommodations = ns("Accommodations")
    val PriceItems = ns("PriceItems")
    val Accommodation = ns("Accommodation")
    
    val priceItemsPath = List(Otds, Accommodations, PriceItems)
    
    val xml = pullXml(inputstream, optimisationStrategy = QNameElemTreeOptimisation)
    
    val itr = iterate(priceItemsPath, xml)
    
    for {
      priceItems <- itr
    } yield {
      val parsedJson = parseXml(priceItems)
      val result = parsedJson.children.head.extract[PriceItems]
      result
    }
      

Как быстро извлечь элементы в конце этого огромного файла, не разбирая все целиком?

Комментарии:

1. Мы не нашли решения в текущей реализации, поэтому мы подготовили изменение самостоятельно. В свободное время мы создадим либо PR, либо fork.

2. PR github.com/chris-twiner/scalesXml/pull/44