有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

用Java实现大文件的XML拆分

我正在尝试创建一个java程序来拆分所选的XML文件

XML文件数据示例:

<EmployeeDetails>
<Employee>
<FirstName>Ben</FirstName>
</Employee>
<Employee>
<FirstName>George</FirstName>
</Employee>
<Employee>
<FirstName>Cling</FirstName>
</Employee>
<EmployeeDetails>

等等,我有一个250mb的XML文件,打开它的外部程序并手动将其拆分以便于其他人阅读(不是所有的笔记本电脑/台式机都能打开这么大的文件),这总是很痛苦的。因此,我决定创建一个Java程序,该程序将具有以下功能: -选择XML文件(已完成) -基于标记的#分割文件,例如(当前文件有100k个标记,我将询问程序用户他/她对分割文件的期望值。例如(每个文件10k) -拆分文件(已完成)

我只是想寻求帮助,了解我如何才能完成第二项任务,已经在3-4天内检查我如何才能完成这项任务,或者这项任务是否可行(在我看来当然可行)

如有任何回复,将不胜感激

干杯, 格林


共 (2) 个答案

  1. # 1 楼答案

    一个简单的解决方案是有序的。如果XML总是有如图所示的换行符,则不需要XML处理

    Path originalPath = Paths.get("... .xml");
    try (BufferedReader in = Files.newBufferedReader(originalPath, StandardCharsets.UTF_8)) {
        String line = in.readLine(); // Skip header line(s)
    
        line = in.readLine();
        for (int fileno; line != null && !line.contains("</EmployeeDetails>"); ++fileno) {
            Path partPath = Paths.get("...-" + fileno + ".xml");
            try (PrintWriter out = new PrintWriter(Files.newBufferedWriter(partPath,
                    StandardCharsets.UTF_8))) {
                int counter = 0;
                out.println("<EmployeeDetails>"); // Write header.
                do {
                    out.println(line);
                    if (line.contains("</Employee>") {
                        ++counter;
                    }
                    line = in.readLine();
                } while (line != null && !line.contains("</EmployeeDetails>")
                        && counter < 1000);
                out.println("</EmployeeDetails>");
            }
        }
    }
    
  2. # 2 楼答案

    假设文档R的根元素有大量名为X的子元素,那么下面的XSLT 2.0转换将每n个X元素拆分一次文件

    <t:transform xmlns:t="http://www.w3.org/1999/XSL/Transform"
      version="2.0">
      <t:param name="N" select="100"/>
      <t:template match="/*">
        <t:for-each-group select="X" 
                          group-adjacent="(position()-1) idiv $N">
          <t:result-document href="{position()}.xml">
            <R>
              <t:copy-of select="current-group()"/>
            </R>
          </t:result-document>
       </t:for-each-group>
      </t:template>
    </t:transform> 
    

    如果希望在流模式下运行它(而不在内存中构建源代码树),那么(a)添加<xsl:mode streamable="yes"/>,并(b)使用XSLT 3.0处理器(Saxon EE或Exselt)运行它