【发布时间】:2016-10-13 17:51:43
【问题描述】:
我正在比较两个图表,一个来自带有简单文字对象的 Turtle 文件,另一个来自具有显式数据类型 IRI 的文件。否则图表相等。
图 A:
<s> <p> "o"
图 B:
<s> <p> "o"^^xsd:string
根据RDF 1.1 (3.3 Literals),“[s] 简单文字是数据类型为 IRI http://www.w3.org/2001/XMLSchema#string 的抽象语法文字的语法糖”。这也反映在具体的语法规范中(N-Triples、Turtle、RDF XML)。
所以我希望我的两个图表都包含一个带有 URI 节点 s 主题、URI 节点 p 谓词和文字节点 o 类型为 xsd:string 对象。基于此,我希望两者之间没有区别。
但实际情况并非如此:
var graphStringA = "<http://example.com/subject> <http://example.com/predicate> \"object\".";
var graphStringB = "<http://example.com/subject> <http://example.com/predicate> \"object\"^^<http://www.w3.org/2001/XMLSchema#string>.";
var graphA = new Graph();
var graphB = new Graph();
StringParser.Parse(graphA, graphStringA);
StringParser.Parse(graphB, graphStringB);
var diff = graphA.Difference(graphB);
差异报告中添加了一个三元组,删除了一个三元组。图表不同,因为对象节点的数据类型不同:graphA.Triples.First().Object.Datatype 什么都不是,而graphB.Triples.First().Object.Datatype 是正确的 URI。
在我看来,要修改这种行为,我必须要么
- 一直到LiteralNode(并改变它对文字节点的假设),或者
- 创建一个新的GraphDiff(考虑到字符串文字的默认数据类型)。
一种解决方法是删除“默认”数据类型:
private static void RemoveDefaultDatatype(IGraph g)
{
var triplesWithDefaultDatatype =
from triple in g.Triples
where triple.Object is ILiteralNode
let literal = triple.Object as ILiteralNode
where literal.DataType != null
where literal.DataType.AbsoluteUri == "http://www.w3.org/2001/XMLSchema#string" || literal.DataType.AbsoluteUri == "http://www.w3.org/2001/XMLSchema#langString"
select triple;
var triplesWithNoDatatype =
from triple in triplesWithDefaultDatatype
let literal = triple.Object as ILiteralNode
select new Triple(
triple.Subject,
triple.Predicate,
g.CreateLiteralNode(
literal.Value,
literal.Language));
g.Assert(triplesWithNoDatatype.ToArray());
g.Retract(triplesWithDefaultDatatype);
}
在 dotnetrdf 中是否有一种方法可以以与 RDF 1.1 一致的方式将简单文字与类型化文字进行比较,而无需采用上述主要重写或解决方法?
【问题讨论】: