你如何用Java格式化一个巨大的XML文件?

时间:2011-12-05 22:42:36

标签: java xml jaxb

我必须使用Java处理4GB的XML文件。

我遇到的问题是XML文件是未格式化的,内容实际上都是一行,没有换行符。

我想格式化XML文件,因此它具有合理的换行符和缩进,因此如果验证失败(我使用JAXB进行解析),我可以轻松找到并检查XML的有问题的部分。

是否有人知道可以在Java中以编程方式应用某些基本XML格式的框架?

6 个答案:

答案 0 :(得分:1)

CkXml将通过getXml方法为您提供所需内容。

CkXml xml = new CkXml();
xml.LoadXml("<root><company><name>Chilkat Software, Inc.</name><url>http://www.chilkatsoft.com/</url><phone>630-784-9670</phone></company></root>");
xml.getXml();

// Output looks like this:
// 
// <?xml version="1.0" encoding="utf-8" ?>
// 
// <root>
//     <company>
//         <name>Chilkat Software, Inc.</name>
//         <url>http://www.chilkatsoft.com/</url>
//         <phone>630-784-9670</phone>
//     </company>
// </root>

还有JTidy适用于HTML,但应该足够好以满足您的需求。

答案 1 :(得分:0)

不确定,但是JTidy呢?

答案 2 :(得分:0)

我假设XML格式正确,只是无效。如果您通过JAXB自己生成XML,则可以在编组对象时输出人类可读的XML。您的Marshaller需要提供格式化输出选项。您可以像这样设置属性:

marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

如果文档是提供给您的(并且您没有生成它),那么像UltraEdit这样的工具最容易使用。它处理大型文档和格式/编辑XML。有免费试用,所以如果这是一个短期发展问题,也许你可以在试用期间解决它。

答案 3 :(得分:0)

我会考虑使用Transformer。以下内容:

Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
StreamResult tranformedDoc = new StreamResult(new StringWriter());
DOMSource source = new DOMSource(new Document()); // Insert content here.

transformer.transform(source, transformedDoc);

// Output string to byte array
return transformedDoc.getWriter().toString().getBytes();

考虑到XML的大小,我不知道这对你来说是否是一个很好的解决方案,但它是一个起点。也可能有更有效的方法来做到这一点,所以会受到批评。

答案 4 :(得分:0)

您可以使用JAXP身份转换,如下所示:

javax.xml.transform.Source xmlSource = 
    new javax.xml.transform.stream.StreamSource(xmlFile);
javax.xml.transform.Result result = 
    new javax.xml.transform.stream.StreamResult(System.out);
javax.xml.transform.TransformerFactory transFact = 
    javax.xml.transform.TransformerFactory.newInstance();
javax.xml.transform.Transformer trans = 
    transFact.newTransformer();
trans.setOutputProperty("indent", "yes")
trans.transform(xmlSource, result);

幸运的是,这将是一个流式转换(如果TransformerFactory是Saxon的话,肯定会这样。)

您可以扩展此方法以将流式验证步骤插入管道,从而无需对数据进行两次传递。如果您在Saxon中执行此操作,则额外的好处是缩进将对模式敏感 - 确保缩进从不干扰模式有效性。

然而,虽然这符合规定的要求,但我不确定它是否会实现基本目标。缩进是为了使数据具有人类可读性。您是否考虑过将使用哪些工具来显示和手动编辑4GB文档?我想不出任何可以完成这项工作的东西,可用性会很糟糕。 4Gb文档很可能是机器生成的,所以如果它无效,你需要修复生成它的程序,而不是数据本身 - 数据中的任何错误都可能会被系统地重复多次。

答案 5 :(得分:0)

设置一个sax解析器 http://docs.oracle.com/javase/6/docs/api/javax/xml/parsers/SAXParser.html

创建自己的内容处理程序并将其分配给sax解析器:

saxParser.getXmlReader().setContentHandler(new MyContentHandler());

ContentHandler提供对解析的所有方面的访问,并且如果它具有不同的子部分,则允许您处理部分的xml,例如:

<doc>
   <app></app>
   <app></app>
</doc>

你可以一次解组一个“app”并在尝试下一个之前处理它。