在Python中解析大型RDF

时间:2010-10-06 01:12:20

标签: python xml sax rdf

我想在python中解析一个非常大的(大约200MB)RDF文件。我应该使用萨克斯还是其他一些图书馆?我很感激我可以构建一些非常基本的代码,比如检索一个标记。

提前致谢。

6 个答案:

答案 0 :(得分:18)

如果您正在寻求快速的表现,那么我建议您将RaptorRedland Python Bindings一起使用。用C语言编写的Raptor的性能比RDFLib好。如果你不想处理C,你可以使用python绑定。

另一个提高性能的建议,忘记解析RDF / XML,使用其他类型的RDF,如Turtle或NTriples。特别解析ntriples比解析RDF / XML要快得多。这是因为ntriples语法更简单。

您可以使用rapper附带的工具将RDF / XML转换为ntriples:

rapper -i rdfxml -o ntriples YOUR_FILE.rdf > YOUR_FILE.ntriples

ntriples文件将包含三元组:

<s1> <p> <o> .
<s2> <p2> "literal" .

并且解析器在处理此结构时往往非常有效。此外,内存方式比RDF / XML更有效,因为正如您所看到的,这种数据结构更小。

下面的代码是一个使用redland python绑定的简单示例:

import RDF
parser=RDF.Parser(name="ntriples") #as name for parser you can use ntriples, turtle, rdfxml, ...
model=RDF.Model()
stream=parser.parse_into_model(model,"file://file_path","http://your_base_uri.org")
for triple in model:
    print triple.subject, triple.predicate, triple.object

如果您在RDF文档中使用相对URI,则基URI是带前缀的URI。您可以在here

中查看有关Python Redland绑定API的文档

如果您不太关心性能,请使用RDFLib,它简单易用。

答案 1 :(得分:8)

我提出你试用rdflib的建议。这是一个很好的快速原型设计,如果您不想将整个图形加载到内存中,BerkeleyDB后端存储可以很好地扩展到数百万个三元组。

import rdflib

graph = rdflib.Graph("Sleepycat")
graph.open("store", create=True)
graph.parse("big.rdf")

# print out all the triples in the graph
for subject, predicate, object in graph:
    print subject, predicate, object

答案 2 :(得分:2)

根据我的经验,SAX非常适合表现,但写作很难。除非我遇到问题,否则我倾向于避免使用它进行编程。

“非常大”取决于机器的RAM。假设您的计算机内存超过1GB,lxmlpyxml或其他一些库e将适用于200mb文件。

答案 3 :(得分:1)

不确定sax是否是最佳解决方案,但IBM似乎认为它适用于使用Python进行高性能XML解析:http://www.ibm.com/developerworks/xml/library/x-hiperfparse/。他们的示例RDF在大小上相形见绌(200MB对1.9GB),所以他们的解决方案应该适合你。

本文的示例开始非常基础并快速启动。

答案 4 :(得分:1)

对于Python中的RDF处理,请考虑使用诸如RDFLib之类的RDF库。如果您还需要三重存储,也可以使用更多重量级解决方案,但这里可能不需要(PySesameneo4jrdfneo4jpy)。

在为RDF编写自己的SAX解析器之前,请查看rdfxml.py

import rdfxml
data = open('data.rdf', 'r').read()
rdfxml.parseRDF(data)

答案 5 :(得分:0)

用于解析RDF文件的非常快速的库是LightRdf。它可以通过pip安装。在项目页面上可以找到代码示例。

如果要从压缩的RDF文件中解析三元组,可以这样进行:

import lightrdf
import gzip

RDF_FILENAME = 'data.rdf.gz'

f = gzip.open(RDF_FILENAME, 'rb')
doc = lightrdf.RDFDocument(f, parser=lightrdf.xml.PatternParser)
for (s, p, o) in doc.search_triples(None, None, None)):
            print(s, p, o)