File: selecting.html

package info (click to toggle)
semweb 1.05%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 4,000 kB
  • ctags: 2,832
  • sloc: cs: 14,483; makefile: 176; perl: 20; sh: 11; ansic: 7
file content (148 lines) | stat: -rw-r--r-- 6,511 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
<html>
	<head>
		<title>SemWeb: Docs: Selecting Statements</title>
		<link rel="stylesheet" type="text/css" href="stylesheet.css"/>
	</head>
	
	<body>

<p><a href="index.html">SemWeb Documentation</a></p>
<h1>Selecting Statements</h1>

<h2>Using statement templates</h2>

<p>In the previous tutorial you saw the <tt>Select</tt> method of <tt>StatementSource</tt>s, which streams all of the statements into a sink.  The name "Select" was derived from SQL syntax, where it's used to retrieve rows that match a criteria.  In SemWeb, Select is used to retreive statements matching a filter.  (And as with SQL, when no criteria is given all statements are retrieved.)</p>

<p>A template is a <tt>Statement</tt> but with subject, predicate, and object possibly <tt>null</tt>.  <tt>null</tt>s are wildcards.  So here are a few examples:</p>

<pre class="code">
store.Select(sink);  // selects all statements, streaming them into sink
store.Select(new Statement(null, null, null), sink);  // the same
store.Select(Statement.All, sink);  // the same, but shorthand

store.Select(new Statement(subj, null, null), sink);  // any statement with that particular subject entity
store.Select(new Statement(subj, pred, null), sink);  // any statement with that particular subject and predicate
store.Select(new Statement(subj, pred, obj), sink);  // just that statement, if it exists in the store
</pre>

<p>The sink can be any <tt>StatementSink</tt>.  This includes <tt>RdfWriters</tt>, which would let 
you write out just a part of a store to a file, and <tt>Stores</tt> like the <tt>MemoryStore</tt>
so that you can move statements between data sources.</p>

<p>Stores provide a few convenience methods.  Two methods are provided for getting all of the subjects found with a given predicate and object, and similarly all objects found with a given subject and predicate.  This can be used to move around in a graph:</p>

<pre class="code">
foreach (Resource r in store.SelectObjects(person, foafname))
	Console.WriteLine("His name is: " + r);
</pre>

<p>Other convenience methods are overrides of Select that rather than sending the results to a sink, load them into memory so that you may for-each over them:</p>

<pre class="code">
foreach (Statement statement in store.Select(new Statement(null, rdftype, foafPerson))) {
	...
}
</pre>

<p>You obviously shouldn't use these on data sources of unbounded size as you wouldn't necessarily want to load the results all into memory.</p>

<p>These convenience methods are only provided in the <tt>Store</tt> class and its subclasses.
If you want to use them on data from a file or other data source that doesn't extend <tt>Store</tt>,
load the data into a <tt>MemoryStore</tt>:</p>

<pre class="code">
Store store = new MemoryStore();
store.Import(RdfReader.LoadFromUri(new Uri("http://dannyayers.com/misc/foaf/foaf.rdf")));
</pre>

<p>Here's an example program that loads a FOAF document and extracts some information using Select:</p>

<pre class="code" file="../examples/select.cs">using System;
using SemWeb;

public class Select {
    const string RDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
    const string FOAF = "http://xmlns.com/foaf/0.1/";
    
    static readonly Entity rdftype = RDF+"type";
    static readonly Entity foafPerson = FOAF+"Person";
    static readonly Entity foafknows = FOAF+"knows";
    static readonly Entity foafname = FOAF+"name";

    public static void Main() {
        Store store = new MemoryStore();
        store.Import(RdfReader.LoadFromUri(new Uri("http://dannyayers.com/misc/foaf/foaf.rdf")));
        
        Console.WriteLine("These are the people in the file:");
        foreach (Statement s in store.Select(new Statement(null, rdftype, foafPerson))) {
            foreach (Resource r in store.SelectObjects(s.Subject, foafname))
                Console.WriteLine(r);
        }
        Console.WriteLine();

        Console.WriteLine("And here's RDF/XML just for some of the file:");
        using (RdfWriter w = new RdfXmlWriter(Console.Out)) {
            store.Select(new Statement(null, foafname, null), w);
            store.Select(new Statement(null, foafknows, null), w);
        }
        Console.WriteLine();    
    }
}
</pre>

<h2>Other notes</h2>

<p>RDF collections, like Bag, Alt, and Seq, in RDF/XML use a strange
<tt>rdf:li</tt> pseudo-property.  <tt>rdf:li</tt> isn't actually a
property.  It is an abbreviation for <tt>rdf:_1</tt>, <tt>rdf:_2</tt>,
etc. in that order.  Thus when you select for members of a collection,
you can't use <tt>rdf:li</tt>.  However, RDFS defines the property
<tt>rdfs:member</tt> which <tt>rdf:_##</tt> properties are all
subproperties of.  The SemWeb stores all recognize the <tt>rdfs:member</tt>
predicate and will match it to any of the <tt>rdf:_##</tt> predicates.<p>

<p>In addition, the <tt>SelectObjects</tt> method of the <tt>Store</tt>
class will automatically sort the objects by their collection order,
where possible, when you call the method with the <tt>rdfs:member</tt> predicate.</p>

<p>Here's an example of that:</p>

<pre class="code" file="../examples/containers.cs">// This example deals with RDF containers.  You can use the rdfs:member
// property to match any rdf:_### (i.e. rdf:li) property.  Or,
// use SelectObjects on the Store, which will return the items
// in sorted order.

using System;
using SemWeb;

public class Containers {

    const string RDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
    const string RDFS = "http://www.w3.org/2000/01/rdf-schema#";
    
    public static void Main() {
        MemoryStore store = new MemoryStore();
        
        Entity container = new Entity("http://www.example.org/#container");
        
        store.Add(new Statement(container, RDF+"type", (Entity)(RDF+"Bag")));
        store.Add(new Statement(container, RDF+"_3", (Literal)"Three"));
        store.Add(new Statement(container, RDF+"_2", (Literal)"Two"));
        store.Add(new Statement(container, RDF+"_1", (Literal)"One"));
        
        // use the rdfs:member property to match for any rdf:_### predicates.
        Entity rdfs_member = (Entity)(RDFS+"member");
        
        using (RdfWriter writer = new N3Writer(Console.Out)) {
            writer.Namespaces.AddNamespace(RDF, "rdf");
            store.Select(new Statement(container, rdfs_member, null), writer);
        }
        
        foreach (Resource r in store.SelectObjects(container, rdfs_member))
            Console.WriteLine(r);
    }
}
</pre>

</body>
</html>