Сплит 1GB Xml файл с использованием Java
У меня есть 1GB Xml файл, как я могу разбить его на хорошо сформированные Xml файлы меньшего размера, используя Java?
Вот пример:
<records>
<record id="001">
<name>john</name>
</record>
....
</records>
Спасибо.
Ответы
Ответ 1
Я бы использовал синтаксический анализатор StAX для этой ситуации. Это предотвратит чтение всего документа за один раз.
- Предоставьте XMLStreamReader локальному корневому элементу под-фрагмента.
- Затем вы можете использовать javax.xml.transform API для создания нового документа из этого фрагмента XML. Это ускорит XMLStreamReader до конца этого фрагмента.
- Повторите шаг 1 для следующего фрагмента.
Пример кода
Для следующего XML выведите каждый раздел "statement" в файл с именем "Значение атрибута учетной записи":
<statements>
<statement account="123">
...stuff...
</statement>
<statement account="456">
...stuff...
</statement>
</statements>
Это можно сделать с помощью следующего кода:
import java.io.File;
import java.io.FileReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamResult;
public class Demo {
public static void main(String[] args) throws Exception {
XMLInputFactory xif = XMLInputFactory.newInstance();
XMLStreamReader xsr = xif.createXMLStreamReader(new FileReader("input.xml"));
xsr.nextTag(); // Advance to statements element
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
while(xsr.nextTag() == XMLStreamConstants.START_ELEMENT) {
File file = new File("out/" + xsr.getAttributeValue(null, "account") + ".xml");
t.transform(new StAXSource(xsr), new StreamResult(file));
}
}
}
Ответ 2
Попробуйте это, используя Saxon-EE 9.3.
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:mode streamable="yes"/>
<xsl:template match="record">
<xsl:result-document href="record-{@id}.xml">
<xsl:copy-of select="."/>
</xsl:result-document>
</xsl:template>
</xsl:stylesheet>
Программное обеспечение не является бесплатным, но если оно экономит вам дневную кодировку, вы легко можете оправдать инвестиции. (Извинения за шаг продаж).
Ответ 3
DOM, STax, SAX все будет делать, но есть свои плюсы и минусы.
- Вы не можете поместить все данные в память в случае DOM.
- Управление программированием проще в случае DOM, затем Stax, а затем SAX.
- Комбинация SAX и DOM - лучший вариант.
- Использование Framework, который уже делает это, может быть лучшим вариантом. Взгляните на smooks. http://www.smooks.org
Надеюсь, что это поможет
Ответ 4
Я почтительно не согласен с Блейзом Доханом. SAX не только трудно использовать, но и очень медленно. С VTD-XML вы можете не только использовать XPath для упрощения логики обработки (10-кратное сокращение кода очень часто), но и намного быстрее, потому что нет избыточного преобразования кодирования/декодирования. Ниже приведен код java с vtd-xml
import java.io.FileOutputStream;
import com.ximpleware.*;
public class split {
public static void main(String[] args) throws Exception {
VTDGen vg = new VTDGen();
if (vg.parseHttpUrl("c:\\xml\\input.xml", true)) {
VTDNav vn = vg.getNav();
AutoPilot ap = new AutoPilot(vn);
ap.selectXPath("/records/record");
int i=-1,j=0;
while ((i = ap.evalXPath()) != -1) {
long l=vn.getElementFragment();
(new FileOutputStream("out"+j+".xml")).write(vn.getXML().getBytes(), (int)l,(int)(l>>32));
j++;
}
}
}
}