有 Java 编程相关的问题?

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

使用java中的SAX解析器从xml文件中提取xml节点(不是文本而是完整的xml)和其他测试节点

我必须读取大的xml文件,每个文件的大小约为500MB。批处理通常在每次运行中处理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:
作者:约翰
打印公司详细信息XML:

<PrintingCompanyDT>
  <Printer>Sam</Printer>
  <Printmachine>Laser</Printmachine>
  <AssocPrint>Oreilly</AssocPrint> 
</PrintingCompanyDT>


2) 书籍:123
作者:梅森 打印公司详细信息XML:

<PrintingCompanyDT>
  <Printer>kelly</Printer>
  <Printmachine>DOTPrint</Printmachine>
  <AssocPrint>Oxford</AssocPrint>
</PrintingCompanyDT>


如果我尝试以常规方式在public void characters(char ch[],int start,int length)方法中添加字符 我得到了以下信息
1) 书籍:ABC:
作者:约翰
打印公司详细信息XML:

Sam 
  Laser
      Oreilly

正是内容和空间

有人能建议如何通过java中的SAX或StaX解析器从xml文件中提取xml节点吗


共 (1) 个答案

  1. # 1 楼答案

    我很想用XOM来完成这类任务,而不是直接使用SAX或StAX。XOM是一种基于树的表示形式,类似于DOM或JDOM,但它支持以一种半流式方式处理XML“细枝”,非常适合于有许多相似元素可以彼此独立处理的情况。此外,每个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文档,依次为每个Book元素调用processBook。在processBook中,您可以作为XOM节点访问整个BookXML树,但不必一次性将整个文件加载到内存中,这是两种情况中最好的一种。在XOM tutorial的“工厂、过滤器、子类化和流式处理”部分有关于这项技术的更多细节

    这个例子只展示了XOM API的最基本部分,但如果需要进行更复杂的处理,它还提供了强大的XPath支持。例如,您可以使用

    Element machine = (Element)book.query("PrintingCompanyDT/PrintMachine").get(0);
    

    或者,如果结构不是很规则,例如如果PrintingCompanyDT有时是Book的直接子级,有时是更深的子级(例如孙子),那么可以使用如下查询:

    Element printingCompanyDT = (Element)book.query(".//PrintingCompanyDT").get(0);
    

    //是在任何级别查找子代的XPath表示法,而/只查找直接子代)