Java: Как разделить поток XML на небольшие документы XML? XPath на потоковом парсере XML? - PullRequest
4 голосов
/ 29 октября 2009

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

<a> <b> ... </b> <b> ... </b> <b> ... </b> <b> ... </b> .... </a>

Мне нужно разбить это на куски

<a> <b> ... </b> <a>

(мне действительно нужны только части <b> .... </b>, пока привязки пространства имен, объявленные выше (например, в <a>), перемещаются в <b>, если это облегчает).

Файл слишком большой для синтаксического анализатора стиля DOM, его нужно сделать потоковым. Есть ли какая-нибудь библиотека XML, которая может это сделать?

[Изменить]

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

Спасибо!

Ответы [ 5 ]

2 голосов
/ 29 октября 2009

API-интерфейс JAXP SAX с фильтром SAX является быстрым и эффективным. Хорошие вступительные фильтры можно увидеть здесь

1 голос
/ 06 декабря 2012

Вы можете сделать это с языком XProc

<?xml version="1.0" encoding="ISO-8859-1"?>
<p:declare-step xmlns:p="http://www.w3.org/ns/xproc" version="1.0">
  <p:load href="in/huge-document.xml"/>
  <p:for-each>
    <p:iteration-source select="/a/b"/>
    <p:wrap match="/b" wrapper="a"/>
    <p:store>
       <p:with-option name="href" select="concat('part', p:iteration-position(), '.xml')">
          <p:empty/>
       </p:with-option>
    </p:store>
  </p:for-each>
</p:declare-step>

Вы можете использовать QuiXProc (реализация Streaming XProc: http://code.google.com/p/quixproc/), чтобы попытаться выполнить потоковую передачу также

1 голос
/ 20 мая 2010

пройти старую школу

StringBuilder buffer = new StringBuilder(1024 * 50);
BufferedReader reader = new BufferedReader(new FileReader(pstmtout));
String line;
while ((line = reader.readLine()) != null) {
  buffer.append(line);
  if (line.equalsIgnoreCase(endStatementTag)) {
    service.handle(buffer.toString());
    buffer.delete(0, buffer.length());
  }
}
1 голос
/ 29 октября 2009

Как разветвитель XML, VTD-XML идеально подходит для этой задачи ... он также более эффективен по памяти, чем DOM. Ключевым методом, упрощающим кодирование, является метод getElementFragment () ... ниже в VTDNav - код Java для разделения input.xml на out0.xml и out1.xml

<a> <b> text1 </b>  <b> text2 </b> </a>

в

<a> <b> text1</b> </a> 

и

<a> <b> text2</b> </a>

с использованием XPath

/a/b

код

import java.io.*;
import com.ximpleware.*;

public class split {
    public static void main(String[] argv) throws Exception{
        VTDGen vg = new VTDGen();
        if (vg.parseFile("c:/split/input.xml", true)){
            VTDNav vn = vg.getNav();
            AutoPilot ap = new AutoPilot(vn);
            ap.selectXPath("/a/b");
            int i=-1,k=0;
            byte[] ba = vn.getXML().getBytes();
            while((i=ap.evalXPath())!=-1){
                FileOutputStream fos = new FileOutputStream("c:/split/out"+k+".xml");
                fos.write("<a>".getBytes());
                long l = vn.getElementFragment();
                fos.write(ba, (int)l, (int)(l>>32));
                fos.write("</a>".getBytes());
                k++;
            }
        }       
    }
}

Для дальнейшего чтения, пожалуйста, посетите http://www.devx.com/xml/Article/36379

0 голосов
/ 29 октября 2009

Мне нравится библиотека XML XOM , поскольку ее интерфейс прост, интуитивно понятен и мощен. Чтобы делать то, что вы хотите с XML, вы можете использовать свой собственный NodeFactory и (например) переопределить метод finishMakingElement(). Если он делает элемент, который вы хотите (в вашем случае, <b>), тогда вы передаете его всему, что вам нужно с ним делать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...