我必须从每个范围大约500MB的大型xml文件中读取。批处理通常在每次运行中处理500个这样的文件。我必须从中提取文本节点,同时从中提取xml节点。我在java中使用了xpath DOM以便于使用,但由于内存问题而无法正常工作,因为我的资源有限。
我打算现在在java中使用SAX或stax - 可以轻松提取文本节点,但我不知道如何使用sax从xml中提取xml节点。
样本:
<?xml version="1.0"?>
<Library>
<Book name = "ABC">
<Author>John</Author>
<PrintingCompanyDT><Printer>Sam</Printer><Printmachine>Laser</Printmachine>
<AssocPrint>Oreilly</AssocPrint> </PrintingCompanyDT>
</Book>
<Book name = "123">
<Author>Mason</Author>
<PrintingCompanyDTv<Printervkelly</Printer><Printmachine>DOTPrint</Printmachine>
<AssocPrint>Oxford</AssocPrint> </PrintingCompanyDT>
</Book>
</Library>
预期结果:
1)书:ABC:
作者:John
PrintCompany Detail XML:
<PrintingCompanyDT>
<Printer>Sam</Printer>
<Printmachine>Laser</Printmachine>
<AssocPrint>Oreilly</AssocPrint>
</PrintingCompanyDT>
2)书:123
作者:梅森
PrintCompany Detail XML:
<PrintingCompanyDT>
<Printer>kelly</Printer>
<Printmachine>DOTPrint</Printmachine>
<AssocPrint>Oxford</AssocPrint>
</PrintingCompanyDT>
如果我尝试在public void characters(char ch [],int start,int length)方法中附加字符的常规方法
我得到以下
1)书:ABC:
作者:John
PrintCompany Detail XML:
Sam
Laser
Oreilly
确切的内容和空格。
有人可以建议如何通过Java中的SAX或StaX解析器从xml文件中提取xml节点。
答案 0 :(得分:0)
我很想使用XOM来完成这类任务,而不是直接使用SAX或StAX。 XOM是一种类似于DOM或JDOM的基于树的表示,但它支持以一种半流方式处理XML“twigs”,非常适合您有许多类似元素可以独立处理的情况。另一个。此外,每个Node
都有一个toXML
方法,可以将节点打印为XML。
import nu.xom.*;
public class LibraryProcessor extends NodeFactory {
private Nodes empty = new Nodes();
private bookNum = 0;
/** Called for each closing tag in the XML */
public Nodes finishMakingElement(Element element) {
if("Book".equals(element.getLocalName())) {
bookNum++;
// process the complete Book element ...
processBook(element);
// ... and throw it away
return empty;
} else {
// process other elements (except Book) in the normal way
return super.finishMakingElement(element);
}
}
private void processBook(Element book) {
System.out.println(bookNum + ": " +
book.getAttributeValue("name"));
System.out.println("Author: " +
book.getFirstChildElement("Author").getValue());
System.out.println("PrintCompany Detail XML: " +
book.getFirstChildElement("PrintingCompanyDT").toXML());
}
public static void main(String[] args) throws Exception {
Builder builder = new Builder(new LibraryProcessor());
builder.build(new File(args[0]));
}
}
这将在XML文档中发挥作用,依次为每个processBook
元素调用Book
一次。在processBook
内,您可以访问整个Book
XML树作为XOM节点,但无需一次性将整个文件加载到内存中 - 两者都是最好的。 XOM tutorial的“工厂,过滤器,子类和流”部分提供了有关此技术的更多详细信息。
此示例仅显示XOM API的最基本位,但如果您需要执行更复杂的处理,它还提供强大的XPath支持。例如,您可以使用
直接访问PrintMachine
中的processBook
元素
Element machine = (Element)book.query("PrintingCompanyDT/PrintMachine").get(0);
或者如果结构不那么规律,例如PrintingCompanyDT
有时是Book
的直接孩子,有时甚至更深(例如孙子),那么你可以使用像
Element printingCompanyDT = (Element)book.query(".//PrintingCompanyDT").get(0);
(//
是用于在任何级别查找后代的XPath表示法,而不是仅查找直接子级的/
。