Python rdflib解析JSON-LD为何仅提取顶层三元组?
问题:rdflib解析JSON-LD仅返回顶层类型三元组,无法获取其他属性
我用Python的rdflib库解析JSON-LD数据,但解析后只输出了顶层的rdf:type三元组,像WebPage的name这类属性都没被解析出来。
我的代码:
from rdflib import Dataset from rdflib.namespace import Namespace, NamespaceManager local_input=""" [ { "@context": "https://schema.org/" }, { "@type": "WebPage", "@id": "https://example.com/glossary/term/", "name": "My Glossary Term", "abstract": "Just my glossary Term.", "datePublished": "2024-03-08T07:52:13+02:00", "dateModified": "2024-03-08T14:54:13+02:00", "url": "https://example.com/glossary/term/", "author": { "@type": "Person", "@id": "https://example.com/", "name": "John Doe" }, "about": [ { "@type": "DefinedTerm", "@id": "https://example.com/glossary/term/#definedTerm" } ] }, { "@type": "DefinedTerm", "@id": "https://example.com/glossary/term/#definedTerm", "name": "My Term", "description": "Just my Term", "inDefinedTermSet": { "@type": "DefinedTermSet", "@id": "https://example.com/glossary/#definedTermSet" } } ] """ SCH = Namespace('https://schema.org/') namespace_manager = NamespaceManager(Dataset(), bind_namespaces='none') namespace_manager.bind('', SCH, override=True) g = Dataset() g.namespace_manager = namespace_manager g.parse(data=local_input, format='json-ld', publicID="http://schema.org/") print(len(g)) import pprint for stmt in g: pprint.pprint(stmt)
输出结果:
2 (rdflib.term.URIRef('https://example.com/glossary/term/'), rdflib.term.URIRef('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), rdflib.term.URIRef('http://schema.org/WebPage'), rdflib.term.URIRef('urn:x-rdflib:default')) (rdflib.term.URIRef('https://example.com/glossary/term/#definedTerm'), rdflib.term.URIRef('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), rdflib.term.URIRef('http://schema.org/DefinedTerm'), rdflib.term.URIRef('urn:x-rdflib:default'))
原因及修复方案
核心问题1:JSON-LD结构不规范
把@context作为数组的单独元素,导致后续节点无法正确关联上下文。JSON-LD规范中,数组形式的图应该将@context放在包含@graph的顶层对象中,或者每个节点都携带@context。
核心问题2:命名空间与publicID不匹配
代码中publicID设为http://schema.org/,但schema.org的标准命名空间是https://schema.org/,同时命名空间绑定和解析时的上下文不统一,导致属性无法被正确映射。
修复后的代码
from rdflib import Dataset from rdflib.namespace import Namespace, NamespaceManager # 修正JSON-LD结构:用@graph包裹节点,@context放在顶层 local_input=""" { "@context": "https://schema.org/", "@graph": [ { "@type": "WebPage", "@id": "https://example.com/glossary/term/", "name": "My Glossary Term", "abstract": "Just my glossary Term.", "datePublished": "2024-03-08T07:52:13+02:00", "dateModified": "2024-03-08T14:54:13+02:00", "url": "https://example.com/glossary/term/", "author": { "@type": "Person", "@id": "https://example.com/", "name": "John Doe" }, "about": [ { "@type": "DefinedTerm", "@id": "https://example.com/glossary/term/#definedTerm" } ] }, { "@type": "DefinedTerm", "@id": "https://example.com/glossary/term/#definedTerm", "name": "My Term", "description": "Just my Term", "inDefinedTermSet": { "@type": "DefinedTermSet", "@id": "https://example.com/glossary/#definedTermSet" } } ] } """ SCH = Namespace('https://schema.org/') namespace_manager = NamespaceManager(Dataset(), bind_namespaces='none') namespace_manager.bind('', SCH, override=True) g = Dataset() g.namespace_manager = namespace_manager # 去掉错误的publicID,或设置为正确的https地址 g.parse(data=local_input, format='json-ld') print(len(g)) import pprint for stmt in g: pprint.pprint(stmt)
修复后效果
运行代码会输出所有三元组,包括WebPage的name、abstract,Author的name等属性,总长度不再是2,而是会包含所有节点的完整属性。
内容的提问来源于stack exchange,提问作者Kaj Kandler
相关产品推荐
相关产品推荐

