我正在使用 dotnetrdf 发送Sparql CONSTRUCT
查询并评估结果IGraph
。
首先,我试图找到代表给定类型个体的所有Uri节点,比如说,
http://www.example.com/InterestingThing
所以,我想使用GetTriplesWithPredicateObject
method,将http://www.w3.org/1999/02/22-rdf-syntax-ns#type
作为谓词并将http://www.example.com/InterestingThing
作为对象传递。该方法需要两个对象实现INode
interface,因此我尝试使用图形GetUriNode
method找到相应的节点。
在查看调试器中的IGraph
对象时,似乎GetUriNode
只能找到图中Nodes
enumeration中包含的内容 - 而且只包含有的Uri节点被用作主语或对象,但没有被用作谓词。
现在,谓词Uri节点显然在那里 - 我可以在浏览图形的Triples
object时看到它们。它们出现在可以直接从该对象检索的Triple
instances中,也可以在同一对象的PredicateNodes
property中找到它们。
有趣的是,IGraph
的某些查询方法(例如GetTriplesWithObject
或GetTriplesWithPredicate
)确实有超载,只接受Uri
而不是INode
- 但{ {3}}没有。
现在,各种可行的解决方法显而易见:
GetTriplesWithPredicate
个实例的Uri
重载,然后手动过滤生成的三元组。PredicateNodes
列表,找到搜索到Uris的内容。所有这些似乎都是不必要的麻烦 - 因为现有的方法建议乍一看,人们应该只能使用GetUriNode
来检索两个节点然后将它们传递给一个节点现成的查询方法,例如GetTriplesWithObjectPredicate
。
因此,我的问题是:
我在dotnetrdf库中或在概念上,在RDF中遗漏了什么,或者这种行为是否会因设计对开发人员造成障碍?
这是一个重现问题的C#测试用例(查询DBpedia):
using System;
using System.Collections.Generic;
using System.Linq;
using VDS.RDF;
using VDS.RDF.Query;
namespace Test
{
class Program
{
public static void Main(string[] args)
{
// Querying
// All entries to analyze are declared to belong to a temporary type, and
// two properties are mapped to temporary property identifiers.
Console.WriteLine();
var endpoint = new SparqlRemoteEndpoint(new Uri("http://dbpedia.org/sparql"));
string query = "PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>\n"
+ "PREFIX ex: <http://www.example.com/>\n"
+ "\n"
+ "CONSTRUCT {\n"
+ " ?r a ex:record.\n"
+ " ?r ex:prop1 ?v1.\n"
+ " ?r ex:prop2 ?v2.\n"
+ "}\n"
+ "WHERE {\n"
+ " {\n"
+ " SELECT ?r\n"
+ " WHERE {\n"
+ " ?r a dbpedia-owl:Work.\n"
+ " FILTER(EXISTS { ?r dbpedia-owl:originalLanguage [] } && EXISTS { ?r dbpedia-owl:author/dbpedia-owl:birthPlace [] }).\n"
+ " } LIMIT 5\n"
+ " }\n"
+ " ?r dbpedia-owl:originalLanguage ?v1.\n"
+ " ?r dbpedia-owl:author/dbpedia-owl:birthPlace ?v2.\n"
+ "}";
Console.WriteLine(query);
Console.WriteLine();
IGraph graph = endpoint.QueryWithResultGraph(query);
PrintNodes("IGraph.Nodes", graph.Nodes);
Console.WriteLine("All triples from IGraph.Triples:");
foreach (var triple in graph.Triples) {
Console.WriteLine("- S: " + NodeToString(triple.Subject));
Console.WriteLine(" P: " + NodeToString(triple.Predicate));
Console.WriteLine(" O: " + NodeToString(triple.Object));
}
Console.WriteLine();
PrintNodes("IGraph.Triples.SubjectNodes", graph.Triples.SubjectNodes);
PrintNodes("IGraph.Triples.PredicateNodes", graph.Triples.PredicateNodes);
PrintNodes("IGraph.Triples.ObjectNodes", graph.Triples.ObjectNodes);
// Graph Analysis
// The following code tries to retrieve exactly the items of the temporary
// type "record".
var typeNode = TryFindUriNode(graph, new Uri(NamespaceMapper.RDF + "type"));
var recordNode = TryFindUriNode(graph, new Uri("http://www.example.com/record"));
Console.WriteLine();
TryFindAllNodes("subjects", graph, graph.Triples.SubjectNodes.OfType<IUriNode>().Select(node => node.Uri));
TryFindAllNodes("predicates", graph, graph.Triples.PredicateNodes.OfType<IUriNode>().Select(node => node.Uri));
TryFindAllNodes("objects", graph, graph.Triples.ObjectNodes.OfType<IUriNode>().Select(node => node.Uri));
Console.WriteLine();
var createdTypeNode = graph.CreateUriNode(new Uri(NamespaceMapper.RDF + "type"));
var createdRecordNode = graph.CreateUriNode(new Uri("http://www.example.com/record"));
if ((typeNode != null) && (recordNode != null)) {
Console.WriteLine("{0} triple(s) with found predicate and found object.",
graph.GetTriplesWithPredicateObject(typeNode, recordNode).Count());
}
if (typeNode != null) {
Console.WriteLine("{0} triple(s) with found predicate and created object.",
graph.GetTriplesWithPredicateObject(typeNode, createdRecordNode).Count());
}
if (recordNode != null) {
Console.WriteLine("{0} triple(s) with created predicate and found object.",
graph.GetTriplesWithPredicateObject(createdTypeNode, recordNode).Count());
}
Console.WriteLine("{0} triple(s) with created predicate and created object.",
graph.GetTriplesWithPredicateObject(createdTypeNode, createdRecordNode).Count());
}
private static string NodeToString(INode node)
{
return string.Format("{0} ({1})", node, node.GetType().Name);
}
private static void PrintNodes(string title, IEnumerable<INode> nodes)
{
Console.WriteLine(title + ":");
foreach (var node in nodes) {
Console.WriteLine("- " + NodeToString(node));
}
Console.WriteLine();
}
private static INode TryFindUriNode(IGraph graph, Uri uri)
{
var result = graph.GetUriNode(uri);
if (result == null) {
Console.WriteLine(uri.ToString() + " was NOT found by IGraph.GetUriNode.");
} else {
Console.WriteLine(uri.ToString() + " WAS found by IGraph.GetUriNode.");
}
return result;
}
private static void TryFindAllNodes(string title, IGraph graph, IEnumerable<Uri> uris)
{
Console.WriteLine("Trying to find all " + title + ":");
foreach (Uri uri in uris) {
TryFindUriNode(graph, uri);
}
}
}
}
这是示例程序的输出:
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
PREFIX ex: <http://www.example.com/>
CONSTRUCT {
?r a ex:record.
?r ex:prop1 ?v1.
?r ex:prop2 ?v2.
}
WHERE {
{
SELECT ?r
WHERE {
?r a dbpedia-owl:Work.
FILTER(EXISTS { ?r dbpedia-owl:originalLanguage [] } && EXISTS { ?r dbpedia-owl:author/dbpedia-owl:birthPlace [] }).
} LIMIT 5
}
?r dbpedia-owl:originalLanguage ?v1.
?r dbpedia-owl:author/dbpedia-owl:birthPlace ?v2.
}
IGraph.Nodes:
- http://dbpedia.org/resource/Electra_(Sophocles) (UriNode)
- http://dbpedia.org/resource/Peer_Gynt (UriNode)
- http://dbpedia.org/resource/Pictures_from_the_Insects'_Life (UriNode)
- http://dbpedia.org/resource/The_Field (UriNode)
- http://dbpedia.org/resource/The_Lady_from_the_Sea (UriNode)
- http://www.example.com/record (UriNode)
- http://dbpedia.org/resource/Ancient_Greek (UriNode)
- http://dbpedia.org/resource/Colonus (UriNode)
- http://dbpedia.org/resource/Norwegian_language (UriNode)
- http://dbpedia.org/resource/Skien (UriNode)
- http://dbpedia.org/resource/Norway (UriNode)
- http://dbpedia.org/resource/Czech_language (UriNode)
- http://dbpedia.org/resource/Kingdom_of_Bohemia (UriNode)
- http://dbpedia.org/resource/Bohemia (UriNode)
- http://dbpedia.org/resource/Mal%C3%A9_Svato%C5%88ovice (UriNode)
- http://dbpedia.org/resource/Austria-Hungary (UriNode)
- http://dbpedia.org/resource/English_language (UriNode)
- http://dbpedia.org/resource/Irish_Free_State (UriNode)
- http://dbpedia.org/resource/Listowel (UriNode)
- http://dbpedia.org/resource/County_Kerry (UriNode)
All triples from IGraph.Triples:
- S: http://dbpedia.org/resource/Electra_(Sophocles) (UriNode)
P: http://www.w3.org/1999/02/22-rdf-syntax-ns#type (UriNode)
O: http://www.example.com/record (UriNode)
- S: http://dbpedia.org/resource/Electra_(Sophocles) (UriNode)
P: http://www.example.com/prop1 (UriNode)
O: http://dbpedia.org/resource/Ancient_Greek (UriNode)
- S: http://dbpedia.org/resource/Electra_(Sophocles) (UriNode)
P: http://www.example.com/prop2 (UriNode)
O: http://dbpedia.org/resource/Colonus (UriNode)
- S: http://dbpedia.org/resource/Peer_Gynt (UriNode)
P: http://www.w3.org/1999/02/22-rdf-syntax-ns#type (UriNode)
O: http://www.example.com/record (UriNode)
- S: http://dbpedia.org/resource/Peer_Gynt (UriNode)
P: http://www.example.com/prop1 (UriNode)
O: http://dbpedia.org/resource/Norwegian_language (UriNode)
- S: http://dbpedia.org/resource/Peer_Gynt (UriNode)
P: http://www.example.com/prop2 (UriNode)
O: http://dbpedia.org/resource/Skien (UriNode)
- S: http://dbpedia.org/resource/Peer_Gynt (UriNode)
P: http://www.example.com/prop2 (UriNode)
O: http://dbpedia.org/resource/Norway (UriNode)
- S: http://dbpedia.org/resource/Pictures_from_the_Insects'_Life (UriNode)
P: http://www.w3.org/1999/02/22-rdf-syntax-ns#type (UriNode)
O: http://www.example.com/record (UriNode)
- S: http://dbpedia.org/resource/Pictures_from_the_Insects'_Life (UriNode)
P: http://www.example.com/prop1 (UriNode)
O: http://dbpedia.org/resource/Czech_language (UriNode)
- S: http://dbpedia.org/resource/Pictures_from_the_Insects'_Life (UriNode)
P: http://www.example.com/prop2 (UriNode)
O: http://dbpedia.org/resource/Kingdom_of_Bohemia (UriNode)
- S: http://dbpedia.org/resource/Pictures_from_the_Insects'_Life (UriNode)
P: http://www.example.com/prop2 (UriNode)
O: http://dbpedia.org/resource/Bohemia (UriNode)
- S: http://dbpedia.org/resource/Pictures_from_the_Insects'_Life (UriNode)
P: http://www.example.com/prop2 (UriNode)
O: http://dbpedia.org/resource/Mal%C3%A9_Svato%C5%88ovice (UriNode)
- S: http://dbpedia.org/resource/Pictures_from_the_Insects'_Life (UriNode)
P: http://www.example.com/prop2 (UriNode)
O: http://dbpedia.org/resource/Austria-Hungary (UriNode)
- S: http://dbpedia.org/resource/The_Field (UriNode)
P: http://www.w3.org/1999/02/22-rdf-syntax-ns#type (UriNode)
O: http://www.example.com/record (UriNode)
- S: http://dbpedia.org/resource/The_Field (UriNode)
P: http://www.example.com/prop1 (UriNode)
O: http://dbpedia.org/resource/English_language (UriNode)
- S: http://dbpedia.org/resource/The_Field (UriNode)
P: http://www.example.com/prop2 (UriNode)
O: http://dbpedia.org/resource/Irish_Free_State (UriNode)
- S: http://dbpedia.org/resource/The_Field (UriNode)
P: http://www.example.com/prop2 (UriNode)
O: http://dbpedia.org/resource/Listowel (UriNode)
- S: http://dbpedia.org/resource/The_Field (UriNode)
P: http://www.example.com/prop2 (UriNode)
O: http://dbpedia.org/resource/County_Kerry (UriNode)
- S: http://dbpedia.org/resource/The_Lady_from_the_Sea (UriNode)
P: http://www.w3.org/1999/02/22-rdf-syntax-ns#type (UriNode)
O: http://www.example.com/record (UriNode)
- S: http://dbpedia.org/resource/The_Lady_from_the_Sea (UriNode)
P: http://www.example.com/prop1 (UriNode)
O: http://dbpedia.org/resource/Norwegian_language (UriNode)
- S: http://dbpedia.org/resource/The_Lady_from_the_Sea (UriNode)
P: http://www.example.com/prop2 (UriNode)
O: http://dbpedia.org/resource/Skien (UriNode)
- S: http://dbpedia.org/resource/The_Lady_from_the_Sea (UriNode)
P: http://www.example.com/prop2 (UriNode)
O: http://dbpedia.org/resource/Norway (UriNode)
IGraph.Triples.SubjectNodes:
- http://dbpedia.org/resource/Electra_(Sophocles) (UriNode)
- http://dbpedia.org/resource/Peer_Gynt (UriNode)
- http://dbpedia.org/resource/Pictures_from_the_Insects'_Life (UriNode)
- http://dbpedia.org/resource/The_Field (UriNode)
- http://dbpedia.org/resource/The_Lady_from_the_Sea (UriNode)
IGraph.Triples.PredicateNodes:
- http://www.w3.org/1999/02/22-rdf-syntax-ns#type (UriNode)
- http://www.example.com/prop1 (UriNode)
- http://www.example.com/prop2 (UriNode)
IGraph.Triples.ObjectNodes:
- http://www.example.com/record (UriNode)
- http://dbpedia.org/resource/Ancient_Greek (UriNode)
- http://dbpedia.org/resource/Colonus (UriNode)
- http://dbpedia.org/resource/Norwegian_language (UriNode)
- http://dbpedia.org/resource/Skien (UriNode)
- http://dbpedia.org/resource/Norway (UriNode)
- http://dbpedia.org/resource/Czech_language (UriNode)
- http://dbpedia.org/resource/Kingdom_of_Bohemia (UriNode)
- http://dbpedia.org/resource/Bohemia (UriNode)
- http://dbpedia.org/resource/Mal%C3%A9_Svato%C5%88ovice (UriNode)
- http://dbpedia.org/resource/Austria-Hungary (UriNode)
- http://dbpedia.org/resource/English_language (UriNode)
- http://dbpedia.org/resource/Irish_Free_State (UriNode)
- http://dbpedia.org/resource/Listowel (UriNode)
- http://dbpedia.org/resource/County_Kerry (UriNode)
Trying to find all subjects:
http://dbpedia.org/resource/Electra_(Sophocles) WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/Peer_Gynt WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/Pictures_from_the_Insects'_Life WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/The_Field WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/The_Lady_from_the_Sea WAS found by IGraph.GetUriNode.
Trying to find all predicates:
http://www.w3.org/1999/02/22-rdf-syntax-ns#type was NOT found by IGraph.GetUriNode.
http://www.example.com/prop1 was NOT found by IGraph.GetUriNode.
http://www.example.com/prop2 was NOT found by IGraph.GetUriNode.
Trying to find all objects:
http://www.example.com/record WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/Ancient_Greek WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/Colonus WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/Norwegian_language WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/Skien WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/Norway WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/Czech_language WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/Kingdom_of_Bohemia WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/Bohemia WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/Mal‚_Svatonovice WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/Austria-Hungary WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/English_language WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/Irish_Free_State WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/Listowel WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/County_Kerry WAS found by IGraph.GetUriNode.
http://www.w3.org/1999/02/22-rdf-syntax-ns#type was NOT found by IGraph.GetUriNode.
http://www.example.com/record WAS found by IGraph.GetUriNode.
5 triple(s) with created predicate and found object.
5 triple(s) with created predicate and created object.
可以看出,IGraph.Nodes
枚举不包含谓词Uris,例如http://www.example.com/prop1
或http://www.w3.org/1999/02/22-rdf-syntax-ns#type
。同样,输出显示GetUriNode
找不到谓词,而主题和对象则是。
答案 0 :(得分:2)
您可以使用CreateURINode中的INodeFactory(IGraph
扩展名)来创建rdf:type
节点,并具有以下内容:
graph.GetTriplesWithPredicateObject(
graph.CreateUriNode( UriFactory.createUri( "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" )), ,
graph.CreateUriNode( UriFactory.createUri( "http://www.example.com/InterestingThing" ))
)
这类似于我在耶拿采用的方法,我使用ResourceFactory.createProperty( http://...ns#type )
之类的方法。 (实际上,Jena有一个常数RDF.type
以方便我使用,但这是我用于未被提前定义为常量的方法。)
答案 1 :(得分:2)
这种行为完全是设计的,只出现在谓词位置的东西被认为是图中的边缘,而不是图中的节点。
由于Working with Graphs文档声明如下:
要选择节点,可以使用可用于查找节点的方法 来自图表(如果存在),这是
GetXNode()
方法,其中X 是要检索的节点的类型。请注意,此方法仅适用 如果给定值作为图中的节点存在,则返回一个值,即 它出现在此图中三元组的主题/对象位置。注意:如果您只想获取其他用法的Node实例 无论它是否已存在于您应该使用的图表中 取而代之的是
CreateXNode()
方法。
也许GetEdge()
和相应的Edges
属性会有用吗?