How to compare simple and typed literals in dotnetrdf?

I compare two graphs, one from a Turtle file with simple literal objects, and the other from a file with explicit IRI data types. The graphs are otherwise equal.

Chart A:

<s> <p> "o"

Chart B:

<s> <p> "o"^^xsd:string

According to RDF 1.1 (3.3 Literals) , "[s] imple literals are syntactic sugar for abstract syntax literals with an IRI data type of http://www.w3.org/2001/XMLSchema#string ". This is also reflected in specific syntax specifications ( N-Triples , Turtle , RDF XML ).

Therefore, I would expect that both of my graphs consist of one triple with the URI object node, the predicate URI node p and the literal node o with type xsd: string object. Based on this, I would expect that there will be no difference between them.

However, in practice this is not so:

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);

There is one added and one removed tee in the differences report. Graphs are different because the data types for the nodes of an object are different: graphA.Triples.First().Object.Datatypenothing, but graphB.Triples.First().Object.Datatypea valid URI.


It seems to me that to change this behavior I will have to either

  • go to LiteralNode (and change its assumptions about literal nodes) or
  • create a new GraphDiff (which takes into account the default data type for string literals).

The workaround is to remove the default data types:

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, , ?

+4
2

dotNetRDF RDF 1.1, . , , , .

, , API- RDF. xsd:string , , HandleTriple(Triple t) .

+3

API- Handlers RobV:

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;
    }
}
+3

Source: https://habr.com/ru/post/1657645/


All Articles