我比较两个图,一个是来自Turtle文件的简单文字对象,另一个是来自具有显式数据类型IRI的文件。图表相同。
图A:
<s> <p> "o"
图B:
<s> <p> "o"^^xsd:string
根据RDF 1.1 (3.3 Literals),&#34; [s]实现文字是抽象语法文字的语法糖,数据类型为IRI http://www.w3.org/2001/XMLSchema#string&#34;。这也反映在具体的语法规范中(N-Triples,Turtle,RDF XML)。
所以我希望我的图表都包含一个带有URI节点 s 主题的三元组,一个URI节点 p 谓词和一个文字节点带有 xsd:string 对象的 o 。基于此,我预计两者之间没有区别。
然而实际情况并非如此:
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。
在我看来,为了修改这种行为,我必须
解决方法是删除&#34;默认&#34;数据类型:
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一致的方式将简单文字与打字文字进行比较,而不采用上述重大改写或解决方法?
答案 0 :(得分:3)
dotNetRDF不符合RDF 1.1标准,也不是我们声称的。有一个分支被重写为合规但不能远程生产就绪。
假设您控制解析过程,您可以使用RDF Handlers API自定义传入数据的处理。然后,您可以根据需要覆盖xsd:string
方法,在文本进入系统时删除隐式HandleTriple(Triple t)
类型。
答案 1 :(得分:3)
按照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<IRdfHandler> 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("<http://example.com/subject> <http://example.com/predicate> \"object\".");
var graphB = Load("<http://example.com/subject> <http://example.com/predicate> \"object\"^^<http://www.w3.org/2001/XMLSchema#string>.");
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;
}
}