Java 如何从基本xml开始创建一个巨大的xml(>;2GB)
我需要开发一些功能来进行一些负载测试。该功能的目标是基于现有xml创建一个xml(大小>2GB)。xml定义了文档和(文档的)集合。每个文档和集合都包含许多定义文档/集合的标记。基本xml大约为100KB。它包含2个文档和一个集合。基于这个xml,我想创建一个新的xml。在生成的xml中,应该多次复制集合和文档(最多100.000次) 一个小的计算表明,生成的xml的大小可能大于2GB。恐怕这不包括DOM解析 基本xml具有以下格式(这不是结果xml,但其结构类似):Java 如何从基本xml开始创建一个巨大的xml(>;2GB),java,xml,sax,stax,Java,Xml,Sax,Stax,我需要开发一些功能来进行一些负载测试。该功能的目标是基于现有xml创建一个xml(大小>2GB)。xml定义了文档和(文档的)集合。每个文档和集合都包含许多定义文档/集合的标记。基本xml大约为100KB。它包含2个文档和一个集合。基于这个xml,我想创建一个新的xml。在生成的xml中,应该多次复制集合和文档(最多100.000次) 一个小的计算表明,生成的xml的大小可能大于2GB。恐怕这不包括DOM解析 基本xml具有以下格式(这不是结果xml,但其结构类似): ... ... ...
...
...
... (文档包含大量信息(元素标记))
... (文档包含大量信息(元素标记))
...
...
在上面的xml中,集合和文档需要复制多次(最多100.000次)。副本中唯一需要更新的值是引用。文档标记包含大量数据,但集合标记相当小。
我的想法是分两步进行:
public static final String LEGAL_ENTITY_NAMESPACE = "http://some/name/space";
public void populate(XMLEventWriter writer, int indent) {
Address address = AddressBuilder.builder().build();
QName addressQName = new QName(LEGAL_ENTITY_NAMESPACE, "address");
writer.setDefaultNamespace(LEGAL_ENTITY_NAMESPACE);
createStartElement(writer, addressQName, Optional.empty(), Optional.empty(), indent);
createElement(writer, new QName(LEGAL_ENTITY_NAMESPACE, "street"), address.getStreet(), indent + 1);
createElement(writer, new QName(LEGAL_ENTITY_NAMESPACE, "houseNumber"), address.getHouseNumber(), indent + 1);
createElement(writer, new QName(LEGAL_ENTITY_NAMESPACE, "boxNumber"), address.getBoxNumber(), indent + 1);
populatorHelper.createElement(writer, new QName(LEGAL_ENTITY_NAMESPACE, "city"), address.getCity(), indent + 1);
createElement(writer, new QName(LEGAL_ENTITY_NAMESPACE, "zipcode"), address.getZipcode(), indent + 1);
createEndElement(writer, addressQName, indent);
}
public void createStartElement(XMLEventWriter writer, QName element, Optional<Iterator<Attribute>> attributes,
Optional<Iterator<Namespace>> nameSpaces, int indent) {
addEndAndTabs(writer, indent);
writer.add(eventFactory.createStartElement(element, attributes.orElse(null), nameSpaces.orElse(null)));
}
public void createElement(XMLEventWriter writer, QName element, String value, int indent) {
addEndAndTabs(writer, indent);
writer.add(eventFactory.createStartElement(element, null, null));
writer.add(eventFactory.createCharacters(value));
writer.add(eventFactory.createEndElement("", "", element.getLocalPart()));
}
public void createEndElement(XMLEventWriter writer, QName element, int indent) {
addEndAndTabs(writer, indent);
writer.add(eventFactory.createEndElement("", "", element.getLocalPart()));
}
public静态最终字符串LEGAL\u ENTITY\u NAMESPACE=”http://some/name/space";
公共void填充(XMLEventWriter编写器,int缩进){
地址=AddressBuilder.builder().build();
QName addressQName=新的QName(法律实体名称空间,“地址”);
setDefaultNamespace(法律实体名称空间);
createStartElement(writer、addressQName、Optional.empty()、Optional.empty()、indent);
createElement(writer,新的QName(LEGAL_ENTITY_NAMESPACE,“street”),address.getStreet(),缩进+1);
createElement(writer,新的QName(合法的实体名称空间,“houseNumber”),address.getHouseNumber(),缩进+1);
createElement(writer,新的QName(LEGAL_ENTITY_名称空间,“boxNumber”),address.getBoxNumber(),indent+1);
createElement(writer,新的QName(LEGAL_ENTITY_NAMESPACE,“city”),address.getCity(),缩进+1);
createElement(writer,新QName(LEGAL_ENTITY_NAMESPACE,“zipcode”),address.getZipcode(),缩进+1);
createEndElement(编写器、地址QName、缩进);
}
public void createStartElement(XMLEventWriter编写器、QName元素、可选属性、,
可选名称空间,int缩进){
附加标签(书写者、缩进);
add(eventFactory.createStartElement(元素、属性、orElse(null)、nameSpaces.orElse(null));
}
public void createElement(XMLEventWriter编写器、QName元素、字符串值、int缩进){
附加标签(书写者、缩进);
add(eventFactory.createStartElement(element,null,null));
add(eventFactory.createCharacters(value));
add(eventFactory.createEndElement(“,”,element.getLocalPart());
}
public void createEndElement(XMLEventWriter编写器、QName元素、int缩进){
附加标签(书写者、缩进);
add(eventFactory.createEndElement(“,”,element.getLocalPart());
}
上面的代码是如何将集合添加到新xml的示例。当然,还有更多的代码。这个很好用。我现在得到的结果是一个基于基本xml的xml,具有大量集合
我仍然需要执行第三步:复制文档(及其所有内容)并更新文档引用。
但是,使用stax,我需要创建每个标记。由于xml中的文档超过1000行(包含大量描述文档的信息),这是不可行的。所以我想知道是否有可能将完整的文档标记(及其所有内容)复制到生成的xml中
总结:
- 基本xml(上面发布的xml)用于生成xml
- 使用stax解析器,基于上述基本xml创建结果xml。结果xml已经包含复制的集合(上面的示例代码)
- 生成的xml(以及复制的集合)保存在一个目录(xml=250 MB)中
- 下一步:复制文档。请记住:文档标记包含大量数据。最终结果将是一个2GB的xml
- 最终的结果应该是一个基于基本xml(见上文)的xml,包含大量文档和集合
public static final String LEGAL_ENTITY_NAMESPACE = "http://some/name/space";
public void populate(XMLEventWriter writer, int indent) {
Address address = AddressBuilder.builder().build();
QName addressQName = new QName(LEGAL_ENTITY_NAMESPACE, "address");
writer.setDefaultNamespace(LEGAL_ENTITY_NAMESPACE);
createStartElement(writer, addressQName, Optional.empty(), Optional.empty(), indent);
createElement(writer, new QName(LEGAL_ENTITY_NAMESPACE, "street"), address.getStreet(), indent + 1);
createElement(writer, new QName(LEGAL_ENTITY_NAMESPACE, "houseNumber"), address.getHouseNumber(), indent + 1);
createElement(writer, new QName(LEGAL_ENTITY_NAMESPACE, "boxNumber"), address.getBoxNumber(), indent + 1);
populatorHelper.createElement(writer, new QName(LEGAL_ENTITY_NAMESPACE, "city"), address.getCity(), indent + 1);
createElement(writer, new QName(LEGAL_ENTITY_NAMESPACE, "zipcode"), address.getZipcode(), indent + 1);
createEndElement(writer, addressQName, indent);
}
public void createStartElement(XMLEventWriter writer, QName element, Optional<Iterator<Attribute>> attributes,
Optional<Iterator<Namespace>> nameSpaces, int indent) {
addEndAndTabs(writer, indent);
writer.add(eventFactory.createStartElement(element, attributes.orElse(null), nameSpaces.orElse(null)));
}
public void createElement(XMLEventWriter writer, QName element, String value, int indent) {
addEndAndTabs(writer, indent);
writer.add(eventFactory.createStartElement(element, null, null));
writer.add(eventFactory.createCharacters(value));
writer.add(eventFactory.createEndElement("", "", element.getLocalPart()));
}
public void createEndElement(XMLEventWriter writer, QName element, int indent) {
addEndAndTabs(writer, indent);
writer.add(eventFactory.createEndElement("", "", element.getLocalPart()));
}
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- IDENTITY TRANSFORM -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="collections">
<xsl:copy>
<xsl:apply-templates select="collection" mode="iter">
<xsl:with-param name="pCount" select="5"/> <!-- ADJUST NUMBER OF ITERATIONS -->
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="collection" mode="iter">
<xsl:param name="pCount"/>
<xsl:if test="$pCount > 0">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
<xsl:apply-templates select="." mode="iter">
<xsl:with-param name="pCount" select="$pCount -1"/>
</xsl:apply-templates>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.OutputKeys;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
public class XSLTransform_JAVA {
public static void main(String[] args) throws IOException, URISyntaxException,
SAXException, ParserConfigurationException,
TransformerException {
// Load XML and XSL Document
String inputXML = "/path/to/Input.xml";
String xslFile = "/path/to/XSLT_Script.xsl";
String outputXML = "/path/to/Output.xml";
Source xslt = new StreamSource(new File(xslFile));
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse (new File(inputXML));
// XSLT Transformation with pretty print
TransformerFactory prettyPrint = TransformerFactory.newInstance();
Transformer transformer = prettyPrint.newTransformer(xslt);
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
transformer.setOutputProperty(OutputKeys.STANDALONE, "yes");
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
// Output Result to File
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(outputXML));
transformer.transform(source, result);
}
}
java org.apache.xalan.xslt.Process -IN source.xml -XSL script.xsl -OUT output.xml
java net.sf.saxon.Transform -s:source.xml -xsl:script.xsl -o:output.xml
java -jar dir/saxon9he.jar -s:source.xml -xsl:script.xsl -o:output.xml