shex 0.6.3 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +98 -87
- data/VERSION +1 -1
- data/lib/shex/algebra/and.rb +3 -12
- data/lib/shex/algebra/each_of.rb +2 -12
- data/lib/shex/algebra/import.rb +6 -0
- data/lib/shex/algebra/not.rb +3 -10
- data/lib/shex/algebra/one_of.rb +2 -12
- data/lib/shex/algebra/operator.rb +26 -13
- data/lib/shex/algebra/or.rb +3 -12
- data/lib/shex/algebra/schema.rb +2 -9
- data/lib/shex/algebra/shape.rb +4 -2
- data/lib/shex/algebra/shape_expression.rb +29 -0
- data/lib/shex/algebra/start.rb +2 -10
- data/lib/shex/algebra/stem.rb +5 -1
- data/lib/shex/algebra/stem_range.rb +3 -1
- data/lib/shex/algebra/triple_constraint.rb +1 -1
- data/lib/shex/algebra/triple_expression.rb +18 -0
- data/lib/shex/algebra.rb +0 -1
- data/lib/shex/meta.rb +25 -38
- data/lib/shex/parser.rb +112 -128
- data/lib/shex/terminals.rb +5 -25
- data/lib/shex.rb +4 -2
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e45bfef778f047d77b25295bf5c41cfc1ed69d040a1ea76dd145734a755faffd
|
4
|
+
data.tar.gz: 91b81f28e0db8a507924627fd94bfc8265301588346715a9102dbf9cea091ab1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e6e9ecf3bbb822070f1d870233eed17ac5ac3a353fca09f8a782b3d31c3538f27d2c4ff2f53336fbcade2b65460c9598309c7bbb2cdb790f90edbc229fab2a17
|
7
|
+
data.tar.gz: 83fa124c1fb95b385ff86fdf707c2a0778261c4f92fce32becca03d7cd29b1e73b7fc56c86746a1dff2d6ba60306d55aa7c81918952142b60f80197bc1edf032
|
data/README.md
CHANGED
@@ -25,27 +25,31 @@ The ShEx gem implements a [ShEx][ShExSpec] Shape Expression engine version 2.0.
|
|
25
25
|
## Examples
|
26
26
|
### Validating a node using ShExC
|
27
27
|
|
28
|
-
require 'rubygems'
|
29
28
|
require 'rdf/turtle'
|
30
29
|
require 'shex'
|
31
30
|
|
32
|
-
shexc
|
31
|
+
shexc = %(
|
33
32
|
PREFIX doap: <http://usefulinc.com/ns/doap#>
|
34
33
|
PREFIX dc: <http://purl.org/dc/terms/>
|
35
|
-
<
|
36
|
-
|
37
|
-
|
38
|
-
doap:
|
39
|
-
doap:
|
40
|
-
|
34
|
+
PREFIX ex: <http://example.com/>
|
35
|
+
|
36
|
+
ex:TestShape EXTRA a {
|
37
|
+
a [doap:Project];
|
38
|
+
( doap:name Literal;
|
39
|
+
doap:description Literal
|
40
|
+
| dc:title Literal;
|
41
|
+
dc:description Literal)+;
|
42
|
+
doap:category IRI*;
|
43
|
+
doap:developer IRI+;
|
44
|
+
doap:implements [<http://shex.io/shex-semantics/>]
|
41
45
|
}
|
42
46
|
)
|
43
47
|
graph = RDF::Graph.load("etc/doap.ttl")
|
44
48
|
schema = ShEx.parse(shexc)
|
45
49
|
map = {
|
46
|
-
"https://rubygems.org/gems/shex" => "TestShape"
|
50
|
+
RDF::URI("https://rubygems.org/gems/shex") => RDF::URI("http://example.com/TestShape")
|
47
51
|
}
|
48
|
-
schema.satisfies?(
|
52
|
+
schema.satisfies?(graph, map)
|
49
53
|
# => true
|
50
54
|
### Validating a node using ShExJ
|
51
55
|
|
@@ -53,92 +57,99 @@ The ShEx gem implements a [ShEx][ShExSpec] Shape Expression engine version 2.0.
|
|
53
57
|
require 'rdf/turtle'
|
54
58
|
require 'shex'
|
55
59
|
|
56
|
-
shexj
|
60
|
+
shexj = %({
|
61
|
+
"@context": "http://www.w3.org/ns/shex.jsonld",
|
57
62
|
"type": "Schema",
|
58
|
-
"
|
59
|
-
"
|
60
|
-
"
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
"
|
65
|
-
|
66
|
-
|
67
|
-
"
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
"type": "EachOf",
|
82
|
-
"expressions": [
|
83
|
-
{
|
84
|
-
"type": "TripleConstraint",
|
85
|
-
"predicate": "http://usefulinc.com/ns/doap#name",
|
86
|
-
"valueExpr": {"type": "NodeConstraint", "nodeKind": "literal"}
|
87
|
-
},
|
88
|
-
{
|
89
|
-
"type": "TripleConstraint",
|
90
|
-
"predicate": "http://usefulinc.com/ns/doap#description",
|
91
|
-
"valueExpr": {"type": "NodeConstraint", "nodeKind": "literal"}
|
92
|
-
}
|
93
|
-
]
|
94
|
-
},
|
95
|
-
{
|
96
|
-
"type": "EachOf",
|
97
|
-
"expressions": [
|
98
|
-
{
|
99
|
-
"type": "TripleConstraint",
|
100
|
-
"predicate": "http://purl.org/dc/terms/title",
|
101
|
-
"valueExpr": {"type": "NodeConstraint", "nodeKind": "literal"}
|
102
|
-
},
|
103
|
-
{
|
104
|
-
"type": "TripleConstraint",
|
105
|
-
"predicate": "http://purl.org/dc/terms/description",
|
106
|
-
"valueExpr": {"type": "NodeConstraint", "nodeKind": "literal"}
|
107
|
-
}
|
108
|
-
]
|
63
|
+
"shapes": [{
|
64
|
+
"id": "http://example.com/TestShape",
|
65
|
+
"type": "Shape",
|
66
|
+
"extra": ["http://www.w3.org/1999/02/22-rdf-syntax-ns#type"],
|
67
|
+
"expression": {
|
68
|
+
"type": "EachOf",
|
69
|
+
"expressions": [{
|
70
|
+
"type": "TripleConstraint",
|
71
|
+
"predicate": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type",
|
72
|
+
"valueExpr": {
|
73
|
+
"type": "NodeConstraint",
|
74
|
+
"values": ["http://usefulinc.com/ns/doap#Project"]
|
75
|
+
}
|
76
|
+
}, {
|
77
|
+
"type": "OneOf",
|
78
|
+
"expressions": [{
|
79
|
+
"type": "EachOf",
|
80
|
+
"expressions": [{
|
81
|
+
"type": "TripleConstraint",
|
82
|
+
"predicate": "http://usefulinc.com/ns/doap#name",
|
83
|
+
"valueExpr": {
|
84
|
+
"type": "NodeConstraint",
|
85
|
+
"nodeKind": "literal"
|
109
86
|
}
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
87
|
+
}, {
|
88
|
+
"type": "TripleConstraint",
|
89
|
+
"predicate": "http://usefulinc.com/ns/doap#description",
|
90
|
+
"valueExpr": {
|
91
|
+
"type": "NodeConstraint",
|
92
|
+
"nodeKind": "literal"
|
93
|
+
}
|
94
|
+
}]
|
95
|
+
}, {
|
96
|
+
"type": "EachOf",
|
97
|
+
"expressions": [{
|
98
|
+
"type": "TripleConstraint",
|
99
|
+
"predicate": "http://purl.org/dc/terms/title",
|
100
|
+
"valueExpr": {
|
101
|
+
"type": "NodeConstraint",
|
102
|
+
"nodeKind": "literal"
|
103
|
+
}
|
104
|
+
}, {
|
105
|
+
"type": "TripleConstraint",
|
106
|
+
"predicate": "http://purl.org/dc/terms/description",
|
107
|
+
"valueExpr": {
|
108
|
+
"type": "NodeConstraint",
|
109
|
+
"nodeKind": "literal"
|
110
|
+
}
|
111
|
+
}]
|
112
|
+
}],
|
113
|
+
"min": 1,
|
114
|
+
"max": -1
|
115
|
+
}, {
|
116
|
+
"type": "TripleConstraint",
|
117
|
+
"predicate": "http://usefulinc.com/ns/doap#category",
|
118
|
+
"valueExpr": {
|
119
|
+
"type": "NodeConstraint",
|
120
|
+
"nodeKind": "iri"
|
118
121
|
},
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
122
|
+
"min": 0,
|
123
|
+
"max": -1
|
124
|
+
}, {
|
125
|
+
"type": "TripleConstraint",
|
126
|
+
"predicate": "http://usefulinc.com/ns/doap#developer",
|
127
|
+
"valueExpr": {
|
128
|
+
"type": "NodeConstraint",
|
129
|
+
"nodeKind": "iri"
|
124
130
|
},
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
131
|
+
"min": 1,
|
132
|
+
"max": -1
|
133
|
+
}, {
|
134
|
+
"type": "TripleConstraint",
|
135
|
+
"predicate": "http://usefulinc.com/ns/doap#implements",
|
136
|
+
"valueExpr": {
|
137
|
+
"type": "NodeConstraint",
|
138
|
+
"values": [
|
139
|
+
"http://shex.io/shex-semantics/"
|
140
|
+
]
|
132
141
|
}
|
133
|
-
|
134
|
-
|
142
|
+
}
|
143
|
+
]
|
135
144
|
}
|
136
145
|
}
|
137
|
-
})
|
146
|
+
]})
|
138
147
|
graph = RDF::Graph.load("etc/doap.ttl")
|
139
148
|
schema = ShEx.parse(shexj, format: :shexj)
|
140
|
-
map = {
|
141
|
-
|
149
|
+
map = {
|
150
|
+
RDF::URI("https://rubygems.org/gems/shex") => RDF::URI("http://example.com/TestShape")
|
151
|
+
}
|
152
|
+
schema.satisfies?(graph, map)
|
142
153
|
# => true
|
143
154
|
|
144
155
|
## Extensions
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.6.
|
1
|
+
0.6.4
|
data/lib/shex/algebra/and.rb
CHANGED
@@ -61,22 +61,13 @@ module ShEx::Algebra
|
|
61
61
|
end
|
62
62
|
|
63
63
|
##
|
64
|
-
# expressions must be ShapeExpressions
|
64
|
+
# expressions must be ShapeExpressions or references to ShapeExpressions
|
65
65
|
#
|
66
66
|
# @return [Operator] `self`
|
67
67
|
# @raise [ShEx::StructureError] if the value is invalid
|
68
68
|
def validate!
|
69
|
-
|
70
|
-
|
71
|
-
when ShapeExpression
|
72
|
-
when RDF::Resource
|
73
|
-
ref = schema.find(op)
|
74
|
-
ref.is_a?(ShapeExpression) ||
|
75
|
-
structure_error("#{json_type} must reference a ShapeExpression: #{ref}")
|
76
|
-
else
|
77
|
-
structure_error("#{json_type} must reference a ShapeExpression: #{ref}")
|
78
|
-
end
|
79
|
-
end
|
69
|
+
validate_expressions!
|
70
|
+
validate_self_references!
|
80
71
|
super
|
81
72
|
end
|
82
73
|
|
data/lib/shex/algebra/each_of.rb
CHANGED
@@ -73,22 +73,12 @@ module ShEx::Algebra
|
|
73
73
|
end
|
74
74
|
|
75
75
|
##
|
76
|
-
# expressions must be TripleExpressions
|
76
|
+
# expressions must be TripleExpressions or references to TripleExpressions
|
77
77
|
#
|
78
78
|
# @return [Operator] `self`
|
79
79
|
# @raise [ShEx::StructureError] if the value is invalid
|
80
80
|
def validate!
|
81
|
-
|
82
|
-
case op
|
83
|
-
when TripleExpression
|
84
|
-
when RDF::Resource
|
85
|
-
ref = schema.find(op)
|
86
|
-
ref.is_a?(TripleExpression) ||
|
87
|
-
structure_error("#{json_type} must reference a TripleExpression: #{ref}")
|
88
|
-
else
|
89
|
-
structure_error("#{json_type} must reference a TripleExpression: #{ref}")
|
90
|
-
end
|
91
|
-
end
|
81
|
+
validate_expressions!
|
92
82
|
super
|
93
83
|
end
|
94
84
|
end
|
data/lib/shex/algebra/not.rb
CHANGED
@@ -45,20 +45,13 @@ module ShEx::Algebra
|
|
45
45
|
end
|
46
46
|
|
47
47
|
##
|
48
|
-
#
|
48
|
+
# expressions must be ShapeExpressions or references to ShapeExpressions and must not reference itself recursively.
|
49
49
|
#
|
50
50
|
# @return [Operator] `self`
|
51
51
|
# @raise [ShEx::StructureError] if the value is invalid
|
52
52
|
def validate!
|
53
|
-
|
54
|
-
|
55
|
-
when RDF::Resource
|
56
|
-
ref = schema.find(expression)
|
57
|
-
ref.is_a?(ShapeExpression) ||
|
58
|
-
structure_error("#{json_type} must reference a ShapeExpression: #{ref}")
|
59
|
-
else
|
60
|
-
structure_error("#{json_type} must reference a ShapeExpression: #{ref}")
|
61
|
-
end
|
53
|
+
validate_expressions!
|
54
|
+
validate_self_references!
|
62
55
|
super
|
63
56
|
end
|
64
57
|
|
data/lib/shex/algebra/one_of.rb
CHANGED
@@ -65,22 +65,12 @@ module ShEx::Algebra
|
|
65
65
|
end
|
66
66
|
|
67
67
|
##
|
68
|
-
# expressions must be TripleExpressions
|
68
|
+
# expressions must be TripleExpressions or references to TripleExpressions
|
69
69
|
#
|
70
70
|
# @return [Operator] `self`
|
71
71
|
# @raise [ShEx::StructureError] if the value is invalid
|
72
72
|
def validate!
|
73
|
-
|
74
|
-
case op
|
75
|
-
when TripleExpression
|
76
|
-
when RDF::Resource
|
77
|
-
ref = schema.find(op)
|
78
|
-
ref.is_a?(TripleExpression) ||
|
79
|
-
structure_error("#{json_type} must reference a TripleExpression: #{ref}")
|
80
|
-
else
|
81
|
-
structure_error("#{json_type} must reference a TripleExpression: #{ref}")
|
82
|
-
end
|
83
|
-
end
|
73
|
+
validate_expressions!
|
84
74
|
super
|
85
75
|
end
|
86
76
|
end
|
@@ -35,8 +35,8 @@ module ShEx::Algebra
|
|
35
35
|
# @option options [RDF::Resource] :id
|
36
36
|
# Identifier of the operator
|
37
37
|
# @raise [TypeError] if any operand is invalid
|
38
|
-
def initialize(*operands)
|
39
|
-
@options =
|
38
|
+
def initialize(*operands, **options)
|
39
|
+
@options = options.dup
|
40
40
|
@operands = operands.map! do |operand|
|
41
41
|
case operand
|
42
42
|
when Array
|
@@ -221,12 +221,19 @@ module ShEx::Algebra
|
|
221
221
|
end
|
222
222
|
|
223
223
|
##
|
224
|
-
# The
|
225
|
-
# @return [
|
224
|
+
# The first expression from {#expressions}.
|
225
|
+
# @return [RDF::Resource, Operand]
|
226
226
|
def expression
|
227
227
|
expressions.first
|
228
228
|
end
|
229
229
|
|
230
|
+
##
|
231
|
+
# References are all operands which are RDF::Resource
|
232
|
+
# @return [RDF::Resource, Operand]
|
233
|
+
def references
|
234
|
+
@references = operands.select {|op| op.is_a?(RDF::Resource)}
|
235
|
+
end
|
236
|
+
|
230
237
|
##
|
231
238
|
# Returns the binary S-Expression (SXP) representation of this operator.
|
232
239
|
#
|
@@ -243,11 +250,6 @@ module ShEx::Algebra
|
|
243
250
|
#
|
244
251
|
# @return [String]
|
245
252
|
def to_sxp
|
246
|
-
begin
|
247
|
-
require 'sxp' # @see https://rubygems.org/gems/sxp
|
248
|
-
rescue LoadError
|
249
|
-
abort "SPARQL::Algebra::Operator#to_sxp requires the SXP gem (hint: `gem install sxp')."
|
250
|
-
end
|
251
253
|
require 'sparql/algebra/sxp_extensions'
|
252
254
|
|
253
255
|
to_sxp_bin.to_sxp
|
@@ -432,6 +434,8 @@ module ShEx::Algebra
|
|
432
434
|
case self
|
433
435
|
when And, Or
|
434
436
|
(obj['shapeExprs'] ||= []) << op.to_h
|
437
|
+
when Not
|
438
|
+
obj['shapeExpr'] = op.to_h
|
435
439
|
else
|
436
440
|
obj['valueExpr'] = op.to_h
|
437
441
|
end
|
@@ -593,22 +597,23 @@ module ShEx::Algebra
|
|
593
597
|
|
594
598
|
##
|
595
599
|
# Enumerate via depth-first recursive descent over operands, yielding each operator
|
600
|
+
# @param [Boolean] include_self
|
596
601
|
# @yield operator
|
597
602
|
# @yieldparam [Object] operator
|
598
603
|
# @return [Enumerator]
|
599
|
-
def each_descendant(&block)
|
604
|
+
def each_descendant(include_self = false, &block)
|
600
605
|
if block_given?
|
601
606
|
|
602
|
-
block.call(self)
|
607
|
+
block.call(self) if include_self
|
603
608
|
|
604
609
|
operands.each do |operand|
|
605
610
|
case operand
|
606
611
|
when Array
|
607
612
|
operand.each do |op|
|
608
|
-
op.each_descendant(&block) if op.respond_to?(:each_descendant)
|
613
|
+
op.each_descendant(true, &block) if op.respond_to?(:each_descendant)
|
609
614
|
end
|
610
615
|
else
|
611
|
-
operand.each_descendant(&block) if operand.respond_to?(:each_descendant)
|
616
|
+
operand.each_descendant(true, &block) if operand.respond_to?(:each_descendant)
|
612
617
|
end
|
613
618
|
end
|
614
619
|
end
|
@@ -631,6 +636,14 @@ module ShEx::Algebra
|
|
631
636
|
@options[:parent]= operator
|
632
637
|
end
|
633
638
|
|
639
|
+
##
|
640
|
+
# Find a ShapeExpression or TripleExpression by identifier
|
641
|
+
# @param [#to_s] id
|
642
|
+
# @return [TripleExpression, ShapeExpression]
|
643
|
+
def find(id)
|
644
|
+
each_descendant(false).detect {|op| op.id == id}
|
645
|
+
end
|
646
|
+
|
634
647
|
##
|
635
648
|
# Ancestors of this Operator
|
636
649
|
# @return [Array<Operator>]
|
data/lib/shex/algebra/or.rb
CHANGED
@@ -67,22 +67,13 @@ module ShEx::Algebra
|
|
67
67
|
end
|
68
68
|
|
69
69
|
##
|
70
|
-
# expressions must be ShapeExpressions
|
70
|
+
# expressions must be ShapeExpressions or references to ShapeExpressions
|
71
71
|
#
|
72
72
|
# @return [Operator] `self`
|
73
73
|
# @raise [ShEx::StructureError] if the value is invalid
|
74
74
|
def validate!
|
75
|
-
|
76
|
-
|
77
|
-
when ShapeExpression
|
78
|
-
when RDF::Resource
|
79
|
-
ref = schema.find(op)
|
80
|
-
ref.is_a?(ShapeExpression) ||
|
81
|
-
structure_error("#{json_type} must reference a ShapeExpression: #{ref}")
|
82
|
-
else
|
83
|
-
structure_error("#{json_type} must reference a ShapeExpression: #{ref}")
|
84
|
-
end
|
85
|
-
end
|
75
|
+
validate_expressions!
|
76
|
+
validate_self_references!
|
86
77
|
super
|
87
78
|
end
|
88
79
|
|
data/lib/shex/algebra/schema.rb
CHANGED
@@ -25,8 +25,9 @@ module ShEx::Algebra
|
|
25
25
|
end
|
26
26
|
|
27
27
|
# (see Operator#initialize)
|
28
|
-
def initialize(*operands)
|
28
|
+
def initialize(*operands, **options)
|
29
29
|
super
|
30
|
+
schema = self
|
30
31
|
each_descendant do |op|
|
31
32
|
# Set schema everywhere
|
32
33
|
op.schema = self
|
@@ -211,14 +212,6 @@ module ShEx::Algebra
|
|
211
212
|
@start ||= operands.detect {|op| op.is_a?(Start)}
|
212
213
|
end
|
213
214
|
|
214
|
-
##
|
215
|
-
# Find a ShapeExpression or TripleExpression by identifier
|
216
|
-
# @param [#to_s] id
|
217
|
-
# @return [TripleExpression, ShapeExpression]
|
218
|
-
def find(id)
|
219
|
-
each_descendant.detect {|op| op.id == id}
|
220
|
-
end
|
221
|
-
|
222
215
|
##
|
223
216
|
# Validate shapes, in addition to other operands
|
224
217
|
# @return [Operator] `self`
|
data/lib/shex/algebra/shape.rb
CHANGED
@@ -106,7 +106,7 @@ module ShEx::Algebra
|
|
106
106
|
end
|
107
107
|
|
108
108
|
##
|
109
|
-
# expression must be a TripleExpression
|
109
|
+
# expression must be a TripleExpression and must not reference itself recursively.
|
110
110
|
#
|
111
111
|
# @return [Operator] `self`
|
112
112
|
# @raise [ShEx::StructureError] if the value is invalid
|
@@ -118,8 +118,10 @@ module ShEx::Algebra
|
|
118
118
|
ref.is_a?(TripleExpression) ||
|
119
119
|
structure_error("#{json_type} must reference a TripleExpression: #{ref}")
|
120
120
|
else
|
121
|
-
structure_error("#{json_type} must
|
121
|
+
structure_error("#{json_type} must be a TripleExpression or reference: #{expression.to_sxp}")
|
122
122
|
end
|
123
|
+
# FIXME: this runs afoul of otherwise legitamate self-references, through a TripleExpression.
|
124
|
+
#!validate_self_references!
|
123
125
|
super
|
124
126
|
end
|
125
127
|
|
@@ -15,5 +15,34 @@ module ShEx::Algebra
|
|
15
15
|
def satisfies?(focus, depth: 0, **options)
|
16
16
|
raise NotImplementedError, "#satisfies? Not implemented in #{self.class}"
|
17
17
|
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# expressions must be ShapeExpressions or references.
|
21
|
+
#
|
22
|
+
# @raise [ShEx::StructureError] if the value is invalid
|
23
|
+
def validate_expressions!
|
24
|
+
expressions.each do |op|
|
25
|
+
case op
|
26
|
+
when ShapeExpression
|
27
|
+
when RDF::Resource
|
28
|
+
ref = schema.find(op)
|
29
|
+
ref.is_a?(ShapeExpression) ||
|
30
|
+
structure_error("#{json_type} must reference a ShapeExpression: #{ref}")
|
31
|
+
else
|
32
|
+
structure_error("#{json_type} must be a ShapeExpression or reference: #{op.to_sxp}")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
##
|
38
|
+
# An Operator with a label must contain a reference to itself.
|
39
|
+
#
|
40
|
+
# @raise [ShEx::StructureError] if the shape is invalid
|
41
|
+
def validate_self_references!
|
42
|
+
return # FIXME: needs to stop at a TripleConstraint
|
43
|
+
each_descendant do |op|
|
44
|
+
structure_error("#{json_type} must not reference itself (#{id}): #{op.to_sxp}") if op.references.include?(id)
|
45
|
+
end
|
46
|
+
end
|
18
47
|
end
|
19
48
|
end
|
data/lib/shex/algebra/start.rb
CHANGED
@@ -30,20 +30,12 @@ module ShEx::Algebra
|
|
30
30
|
end
|
31
31
|
|
32
32
|
##
|
33
|
-
#
|
33
|
+
# expressions must be ShapeExpressions or references to ShapeExpressions
|
34
34
|
#
|
35
35
|
# @return [Operator] `self`
|
36
36
|
# @raise [ShEx::StructureError] if the value is invalid
|
37
37
|
def validate!
|
38
|
-
|
39
|
-
when ShapeExpression
|
40
|
-
when RDF::Resource
|
41
|
-
ref = schema.find(expression)
|
42
|
-
ref.is_a?(ShapeExpression) ||
|
43
|
-
structure_error("#{json_type} must reference a ShapeExpression: #{ref}")
|
44
|
-
else
|
45
|
-
structure_error("#{json_type} must reference a ShapeExpression: #{ref}")
|
46
|
-
end
|
38
|
+
validate_expressions!
|
47
39
|
super
|
48
40
|
end
|
49
41
|
end
|
data/lib/shex/algebra/stem.rb
CHANGED
@@ -66,8 +66,12 @@ module ShEx::Algebra
|
|
66
66
|
NAME = :languageStem
|
67
67
|
|
68
68
|
# (see Stem#match?)
|
69
|
+
# If the operand is empty, than any language will do,
|
70
|
+
# otherwise, it matches the substring up to that first '-', if any.
|
69
71
|
def match?(value, depth: 0)
|
70
|
-
if value.literal? &&
|
72
|
+
if value.literal? &&
|
73
|
+
value.language? &&
|
74
|
+
(operands.first.to_s.empty? || value.language.to_s.match?(%r(^#{operands.first}((-.*)?)$)))
|
71
75
|
status "matched #{value}", depth: depth
|
72
76
|
true
|
73
77
|
else
|
@@ -102,7 +102,9 @@ module ShEx::Algebra
|
|
102
102
|
def match?(value, depth: 0)
|
103
103
|
initial_match = case operands.first
|
104
104
|
when :wildcard then true
|
105
|
-
when RDF::Literal
|
105
|
+
when RDF::Literal
|
106
|
+
value.language? &&
|
107
|
+
(operands.first.to_s.empty? || value.language.to_s.match?(%r(^#{operands.first}((-.*)?)$)))
|
106
108
|
else false
|
107
109
|
end
|
108
110
|
|
@@ -97,7 +97,7 @@ module ShEx::Algebra
|
|
97
97
|
ref.is_a?(ShapeExpression) ||
|
98
98
|
structure_error("#{json_type} must reference a ShapeExpression: #{ref}")
|
99
99
|
else
|
100
|
-
structure_error("#{json_type} must
|
100
|
+
structure_error("#{json_type} must be a ShapeExpression or reference: #{expresson.to_sxp}")
|
101
101
|
end
|
102
102
|
super
|
103
103
|
end
|
@@ -16,6 +16,24 @@ module ShEx::Algebra
|
|
16
16
|
raise NotImplementedError, "#matches Not implemented in #{self.class}"
|
17
17
|
end
|
18
18
|
|
19
|
+
##
|
20
|
+
# expressions must be TripleExpressions or references to TripleExpressions
|
21
|
+
#
|
22
|
+
# @raise [ShEx::StructureError] if the value is invalid
|
23
|
+
def validate_expressions!
|
24
|
+
expressions.each do |op|
|
25
|
+
case op
|
26
|
+
when TripleExpression
|
27
|
+
when RDF::Resource
|
28
|
+
ref = schema.find(op)
|
29
|
+
ref.is_a?(TripleExpression) ||
|
30
|
+
structure_error("#{json_type} must reference a TripleExpression: #{ref}")
|
31
|
+
else
|
32
|
+
structure_error("#{json_type} must be a TripleExpression or reference: #{op.to_sxp}")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
19
37
|
##
|
20
38
|
# Included TripleConstraints
|
21
39
|
# @return [Array<TripleConstraints>]
|