[英]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.