关于python:如何用RDFLib解析.ttl文件?

How to parse .ttl files with RDFLib?

我有一份.ttl格式的文件。它有4个属性/列,包含以下形式的四倍:

  • (id, student_name, student_address, student_phoneno)
  • (id, faculty_name, faculty_address, faculty_phoneno)
  • 我知道如何用rdflib解析.n3形式的三元组;

    1
    2
    3
    from rdflib import Graph
    g = Graph()
    g.parse("demo.nt", format="nt")

    但我不确定如何解析这四个词。

    我的目的是解析和提取与特定ID相关的所有信息。学生和教师的ID可以相同。

    如何使用rdflib来处理这些四元组,并使用它基于id进行聚合?

    来自.ttl文件的示例代码段:

    1
    2
    3
    4
    5
    #@ <id1>
    <Alice> <USA> <12345>

    #@ <id1>
    <Jane> <France> <78900>


    Turtle是Notation 3语法的一个子集,因此rdflib应该能够使用format='n3'解析它。检查rdflib是否保留注释(id在您的样本中的注释(#...中指定)。如果没有,并且输入格式如示例中所示简单,则可以手动分析它:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    import re
    from collections import namedtuple
    from itertools import takewhile

    Entry = namedtuple('Entry', 'id name address phone')

    def get_entries(path):
        with open(path) as file:
            # an entry starts with `#@` line and ends with a blank line
            for line in file:
                if line.startswith('#@'):
                    buf = [line]
                    buf.extend(takewhile(str.strip, file)) # read until blank line
                    yield Entry(*re.findall(r'<([^>]+)>', ''.join(buf)))

    print("
    "
    .join(map(str, get_entries('example.ttl'))))

    输出:

    1
    2
    Entry(id='id1', name='Alice', address='USA', phone='12345')
    Entry(id='id1', name='Jane', address='France', phone='78900')

    要将条目保存到数据库,请执行以下操作:

    1
    2
    3
    4
    5
    6
    7
    import sqlite3

    with sqlite3.connect('example.db') as conn:
        conn.execute('''CREATE TABLE IF NOT EXISTS entries
                 (id text, name text, address text, phone text)'''
    )
        conn.executemany('INSERT INTO entries VALUES (?,?,?,?)',
                         get_entries('example.ttl'))

    如果需要在python中进行一些后处理,则按id分组:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import sqlite3
    from itertools import groupby
    from operator import itemgetter

    with sqlite3.connect('example.db') as c:
        rows = c.execute('SELECT * FROM entries ORDER BY id LIMIT ?', (10,))
        for id, group in groupby(rows, key=itemgetter(0)):
            print("%s:
    \t%s"
    % (id,"
    \t"
    .join(map(str, group))))

    输出:

    1
    2
    3
    id1:
        ('id1', 'Alice', 'USA', '12345')
        ('id1', 'Jane', 'France', '78900')

    您可以按照Snakes和Coffee的建议进行操作,只需使用yield语句将该函数(或其代码)包装在一个循环中。这将创建一个生成器,可以反复调用该生成器来动态创建下一行的dict。假设您要将这些内容写入CSV,例如,使用蛇的parse-to-dict:

    1
    2
    3
    4
    5
    import re
    import csv

    writer = csv.DictWriter(open(outfile,"wb"), fieldnames=["id","name","address","phone"])
    # or whatever

    您可以创建一个生成器作为函数或具有内联理解:

    1
    2
    3
    def dict_generator(lines):
        for line in lines:
            yield parse_to_dict(line)

    --或者——

    1
    dict_generator = (parse_to_dict(line) for line in lines)

    这些都差不多。此时,您可以通过调用dict_generator.next()得到一条听写解析的行,并且您可以一次神奇地得到一条——不涉及额外的RAM抖动。

    如果你有16千兆的原始数据,你可能会考虑制造一个发电机来拉线。它们真的很有用。

    有关So和某些文档中生成器的详细信息:您可以使用python生成器函数做什么?http://wiki.python.org/moin/generators网站


    目前似乎没有这样的库来解析Turtle-Terse RDF三语言

    正如您已经知道的语法一样,最好的选择是使用pyparsing首先创建语法,然后分析文件。

    我还建议根据您的需要调整以下ebnf实现