
rdflib 默认无法解析非标准结构的 json-ld(如数组根节点或分散的上下文),需改用 @graph + 统一 @context 的规范格式,才能完整提取嵌套实体(如 author.name、about.name)对应的 rdf 三元组。
rdflib 默认无法解析非标准结构的 json-ld(如数组根节点或分散的上下文),需改用 @graph + 统一 @context 的规范格式,才能完整提取嵌套实体(如 author.name、about.name)对应的 rdf 三元组。
在使用 rdflib 解析 JSON-LD 时,一个常见误区是将多个独立 JSON 对象以数组形式(如 [{...}, {...}])作为输入——这种结构不符合 JSON-LD 规范,rdflib 的 parse() 方法会忽略未显式声明为图成员(即未置于 @graph 数组中)的嵌套对象,导致仅解析顶层资源的 @type 和 @id,而丢失所有属性值(如 name、author.name、about.name 等)。
✅ 正确做法是:
- 将整个数据封装为单个 JSON 对象;
- 使用 @context 统一声明命名空间(推荐使用 "@vocab": "https://www.php.cn/link/b8eadb229854b2add23d0371cc31b937" 简化前缀);
- 所有资源(包括嵌套实体)必须作为 @graph 数组中的独立条目显式列出,并通过 @id 关联;
- 嵌套关系(如 author、about、inDefinedTermSet)应使用 {"@id": "..."} 引用已有资源,而非内联对象(否则 rdflib 无法识别其为已命名节点)。
以下是可被 rdflib 完整解析的合规 JSON-LD 示例:
{
"@context": {
"@vocab": "https://www.php.cn/link/b8eadb229854b2add23d0371cc31b937"
},
"@graph": [
{
"@id": "https://example.com/glossary/#definedTermSet",
"@type": "DefinedTermSet"
},
{
"@id": "https://example.com/",
"@type": "Person",
"name": "John Doe"
},
{
"@id": "https://example.com/glossary/term/",
"@type": "WebPage",
"about": {"@id": "https://example.com/glossary/term/#definedTerm"},
"abstract": "Just my glossary Term",
"author": {"@id": "https://example.com/"},
"dateModified": "2024-03-08T14:54:13+02:00",
"datePublished": "2024-03-08T07:52:13+02:00",
"name": "My Glossary Term",
"url": "https://example.com/glossary/term/"
},
{
"@id": "https://example.com/glossary/term/#definedTerm",
"@type": "DefinedTerm",
"inDefinedTermSet": {"@id": "https://example.com/glossary/#definedTermSet"},
"name": "My Term"
}
]
}
对应 Python 解析代码(简洁可靠,无需手动绑定命名空间):
from rdflib import Dataset
data = '''{ ... }''' # 上述合规 JSON-LD 字符串
g = Dataset()
g.parse(data=data, format="json-ld")
print(f"Total triples: {len(g)}") # ✅ 输出远大于 2(含 name、author、about 等所有属性)
# 验证关键属性是否解析成功
for s, p, o, c in g.triples((None, None, None)):
if "name" in str(p):
print(f"{s} → {p} → {o}")
⚠️ 注意事项:
- ❌ 避免使用数组作为 JSON-LD 根节点([{...}, {...}]),rdflib 将其视为非法文档;
- ❌ 不要在 @graph 外定义 @context,否则上下文不生效;
- ❌ 嵌套对象(如 "author": {"@type": "Person", "name": "..."})若未声明 @id,rdflib 会生成空白节点(BNode),但属性可能无法正确关联到主资源;
- ✅ 推荐始终为每个实体分配稳定 @id,并通过引用({"@id": "..."})建立关系,确保语义清晰且可复用。
总结:JSON-LD 解析质量高度依赖输入结构的规范性。遵循 W3C JSON-LD 1.1 标准(特别是 @graph + 显式 @id 模式),是 rdflib 正确展开嵌套语义、生成完整 RDF 图的前提。










