Java 如何有效地使大型XML文件在web应用程序中可搜索?

Java 如何有效地使大型XML文件在web应用程序中可搜索?,java,xml,sax,Java,Xml,Sax,我有一个XML文档,需要通过webapp进行搜索。文档当前只有6mb。。但是可能会非常大,因此从我的研究来看,SAX似乎是一条出路 所以我的问题是,给定一个搜索词,我是否: 我是否将文档加载到内存中一次(加载到bean列表中,然后 将其存储在内存中?然后在需要时搜索它? 或 分析文档以查找所需的搜索词,并仅添加 与bean列表的匹配项?然后对每个人重复这个过程 搜索 我对网络应用没有那么丰富的经验,但我正试图找出实现这一点的最佳方法,有没有人对Tomcat、SAX和Java网络应用有什么建议,哪

我有一个XML文档,需要通过webapp进行搜索。文档当前只有6mb。。但是可能会非常大,因此从我的研究来看,SAX似乎是一条出路

所以我的问题是,给定一个搜索词,我是否:

  • 我是否将文档加载到内存中一次(加载到bean列表中,然后 将其存储在内存中?然后在需要时搜索它? 或

  • 分析文档以查找所需的搜索词,并仅添加 与bean列表的匹配项?然后对每个人重复这个过程 搜索

  • 我对网络应用没有那么丰富的经验,但我正试图找出实现这一点的最佳方法,有没有人对Tomcat、SAX和Java网络应用有什么建议,哪种是最佳的

    问候,,
    Nate

    假设您的搜索字段是您已知的字段,例如,让xml的结构为:

    <a>....</a>
    <x>
    <y>search text1</y>
    <z>search text2</z>
    </x>
    <b>...</b>
    
    解析器和

    要了解STAX和SAX之间的区别,请参阅:

    使用这些API可以避免将整个文档存储在内存中。当遇到“x”标记时,使用STAX解析器解析文档,并使用JAXB将其加载到内存(javabean)中

    注意:只有x及其子项将被加载到内存中,而不是到目前为止解析的整个文档。 不要使用任何使用DOM解析器的方法

    仅加载文档中存在搜索字段的部分的示例代码

    XMLInputFactory xif = XMLInputFactory.newFactory();
    StreamSource xml = new StreamSource("file");
    XMLStreamReader xsr = xif.createXMLStreamReader(xml);
    xsr.nextTag();
    while(!xsr.getLocalName().equals("x")) {
        xsr.nextTag();
    }
    
    JAXBContext jc = JAXBContext.newInstance(X.class);
    Unmarshaller unmarshaller = jc.createUnmarshaller();
    JAXBElement<Customer> jb = unmarshaller.unmarshal(xsr, X.class);
    xsr.close();
    
    X x = jb.getValue();
    System.out.println(x.y.content);
    
    XMLInputFactory xif=XMLInputFactory.newFactory();
    StreamSource xml=新的StreamSource(“文件”);
    XMLStreamReader xsr=xif.createXMLStreamReader(xml);
    xsr.nextTag();
    而(!xsr.getLocalName().equals(“x”)){
    xsr.nextTag();
    }
    JAXBContext jc=JAXBContext.newInstance(X.class);
    Unmarshaller Unmarshaller=jc.createUnmarshaller();
    JAXBElement jb=unmarshaller.unmarshal(xsr,X.class);
    xsr.close();
    X=jb.getValue();
    系统输出打印项次(x.y.content);
    

    现在您有了返回相应字段的字段内容。当用户再次在“x”下搜索同一字段时,请从内存中给出结果,并避免再次解析XML。

    使用XPath或XQuery搜索文件可能非常快(相当快,除非每秒处理数千个事务)。需要时间的是解析文件——在内存中构建一个树,以便XPath或XQuery可以搜索它。因此(正如其他人所说)很大程度上取决于文件内容更改的频率。如果更改不频繁,您应该能够在共享内存中保留文件的副本,因此解析成本将在多次搜索中分摊。但如果变化频繁,事情就会变得更复杂。您可以尝试在磁盘上保存原始XML的副本,在内存中保存已解析XML的副本,并保持两者同步。或者您可以咬紧牙关,转而使用XML数据库——最初的努力最终会有回报


    只有在每次搜索文件时都要对其进行解析时,您关于“SAX就是要走的路”的评论才是正确的。如果您正在这样做,那么您希望以最快的方式解析文件。但更好的方法是避免在每次搜索时重新解析它。

    当您说您的XML文件可能非常大时,我假设您不想将其保留在内存中。如果您希望它是可搜索的,我知道您希望索引访问,而不是每次完全读取。IMHO,实现这一点的唯一方法是解析文件并将数据加载到轻量级文件数据库(Derby、HSQL或H2)中,并向数据库添加相关索引。数据库允许对非内存数据进行索引搜索,而XML文件不允许。

    您想在XML文件中搜索什么?只是想知道简单的正则表达式是否有帮助?“超大”意味着预处理。用SQL术语来说,这将避免全表扫描。您的XML可以在运行时修改吗?如何在XML文件中执行搜索?你会把它用作(非常)小的数据库还是类似的?您希望从查询中得到什么样的结果:搜索行的当前值、XML的一小部分相关数据、XML之外但通过XML索引的另一个数据?有几个问题需要我们对你真正的问题有一个具体的了解。我甚至可以说您将XML加载到一个字符串中,然后仅对该字符串执行搜索,但这可能不是最好的主意。XML文档的更改频率和读/写执行频率是多少?这个庞大的XML文件的用途是什么?您的应用程序将如何与it交互(您将在it中搜索什么以及搜索频率如何)?是否可以将XML分割成多个部分?您有XML的XSD吗?XML的内容在运行时会发生变化吗?