繁体   English   中英

从大型xml文件中提取大xml块的最佳方法

[英]Best way to extract big xml block from large xml file

我使用XPath从XML文件中提取大块。 我的xml文件很大,它们来自PubMed。 我的文件类型的一个例子是:

ftp://ftp.ncbi.nlm.nih.gov/pubmed/baseline/medline17n0001.xml.gz

所以,通过使用

 Node result = (Node)xPath.evaluate("PubmedArticleSet/PubmedArticle[MedlineCitation/PMID = "+PMIDtoSearch+"]", doc, XPathConstants.NODE);

我收到了PMIDtoSearch的文章,所以它很完美。 但这需要很长时间。 我必须做大约800.000次,所以使用这个解决方案需要两个多月。 有些块有超过400行,每个xml文件有超过4百万行。

我也尝试过像这个getElementsByTagName函数这样的解决方案,但它几乎需要相同的时间。

你知道如何改进解决方案吗?

谢谢。

我把你的文件加载到exists-db然后执行你的查询,基本上这样:

xquery version "3.0";
let $medline := '/db/Medline/Data'
let $doc := 'medline17n0001.xml'
let $PMID := request:get-parameter("PMID", "")
let $article := doc(concat($medline,'/',$doc))/PubmedArticleSet/PubmedArticle[MedlineCitation/PMID=$PMID]
return
$article

该文档在400毫秒内从远程服务器返回。 如果我加强了那个服务器,我会期望少于那个,它可以处理多个并发请求。 或者,如果您拥有本地更快的一切。

自己尝试一下,我将数据留在测试服务器中(并记住这是在远程查询加利福尼亚的亚马逊微服务器):

http://54.241.15.166/get-article2.xq?PMID=8

http://54.241.15.166/get-article2.xq?PMID=6

http://54.241.15.166/get-article2.xq?PMID=1

当然,整个文件都在那里。 您只需将该查询更改为PMID = 667或999或其他任何内容,然后返回目标文档片段。

正如@KevinBrown所说,数据库可能是正确的答案。 但是,如果这是一次性过程,可能解决方案比您的解决方案工作得快得多,但不需要学习如何设置XML数据库的复杂性。

在您使用的方法中,有两个主要成本:解析XML文档以在内存中创建树,然后搜索内存中的文档以查找特定的ID值。 我猜想解析成本可能比搜索成本高出一个数量级。

因此,为此获得良好表现有两个因素:

  • 首先,您需要确保只解析每个源文档一次(而不是每个查询一次)。 你还没告诉我们足够让我知道你是否已经这样做了。

  • 第二,如果要从单个文档中检索许多数据块,则需要在不对每个文档进行串行搜索的情况下执行此操作。 实现此目的的最佳方法是使用构建索引的查询处理器来优化查询(例如Saxon-EE)。 或者,您可以“手动”构建索引,例如使用XQuery 3.1映射,或者使用XSLT中的xsl:key功能。

这是执行xpath查询的代码..在我的笔记本电脑上,结果看起来不错..不管pmid值大约需要1秒。 你打算如何提取文本。 我可以更新代码来定位它。

public static void main(String[] args) throws VTDException{
        VTDGen vg = new VTDGen();
        if (!vg.parseFile("d:\\xml\\medline17n0001.xml", false))
            return;
        VTDNav vn = vg.getNav();
        AutoPilot ap = new AutoPilot(vn);
        System.out.println("nesting level"+vn.getNestingLevel());
        String PMIDtoSearch =  "30000";
        ap.selectXPath("/PubmedArticleSet/PubmedArticle[MedlineCitation/PMID = "+PMIDtoSearch+"]");
        System.out.println("====>"+ap.getExprString());
        int i=0,count=0;
        System.out.println(" token count ====> "+ vn.getTokenCount() );
        while((i=ap.evalXPath())!=-1){
            count++;
            System.out.println("string ====>"+vn.toString(i));
        }
        System.out.println(" count ===> "+count);
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM