如何比较dotnetrdf中的简单和类型文字?

我正在比较两个图,一个来自Turtle文件和简单的文字对象,另一个来自具有显式数据类型IRI的文件。 图表在其他方面是相同的。

图A:

 

"o"

图B:

  

"o"^^xsd:string

根据RDF 1.1(3.3 Literals) ,“[s] implementation literals是抽象语法文字的语法糖,数据类型为IRI http://www.w3.org/2001/XMLSchema#string ”。 这也反映在具体的语法规范中( N-Triples , Turtle , RDF XML )。

所以我希望我的两个图都包含一个带有URI节点主题的三元组,一个URI节点p谓词,以及一个类型为xsd:string object的文字节点o 。 基于此,我希望两者之间没有区别。

但实际情况并非如此:

 var graphStringA = "  \"object\"."; var graphStringB = "  \"object\"^^."; 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一致的方式将简单文字与类型文字进行比较,而无需采用上述重大改写或解决方法?

dotNetRDF不符合RDF 1.1标准,也不是我们声称的。 有一个分支被重写为合规但不是远程生产就绪。

假设您控制解析过程,您可以使用RDF Handlers API自定义传入数据的处理 。 然后,您可以通过根据需要覆盖HandleTriple(Triple t)方法,在文本进入系统时删除隐式xsd:string类型。

根据RobV的回答使用Handlers API:

 class StripStringHandler : BaseRdfHandler, IWrappingRdfHandler { protected override bool HandleTripleInternal(Triple t) { if (t.Object is ILiteralNode) { var literal = t.Object as ILiteralNode; if (literal.DataType != null && (literal.DataType.AbsoluteUri == "http://www.w3.org/2001/XMLSchema#string" || literal.DataType.AbsoluteUri == "http://www.w3.org/2001/XMLSchema#langString")) { var simpleLiteral = this.CreateLiteralNode(literal.Value, literal.Language); t = new Triple(t.Subject, t.Predicate, simpleLiteral); } } return this.handler.HandleTriple(t); } private IRdfHandler handler; public StripStringHandler(IRdfHandler handler) : base(handler) { this.handler = handler; } public IEnumerable InnerHandlers { get { return this.handler.AsEnumerable(); } } protected override void StartRdfInternal() { this.handler.StartRdf(); } protected override void EndRdfInternal(bool ok) { this.handler.EndRdf(ok); } protected override bool HandleBaseUriInternal(Uri baseUri) { return this.handler.HandleBaseUri(baseUri); } protected override bool HandleNamespaceInternal(string prefix, Uri namespaceUri) { return this.handler.HandleNamespace(prefix, namespaceUri); } public override bool AcceptsAll { get { return this.handler.AcceptsAll; } } } 

用法:

 class Program { static void Main() { var graphA = Load("  \"object\"."); var graphB = Load("  \"object\"^^."); var diff = graphA.Difference(graphB); Debug.Assert(diff.AreEqual); } private static IGraph Load(string source) { var result = new Graph(); var graphHandler = new GraphHandler(result); var strippingHandler = new StripStringHandler(graphHandler); var parser = new TurtleParser(); using (var reader = new StringReader(source)) { parser.Load(strippingHandler, reader); } return result; } }