rdf-microdata 1.1.1.3 → 1.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README +3 -1
- data/VERSION +1 -1
- data/lib/rdf/microdata/reader.rb +75 -43
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b6e7808ba9a859c54b20c2d1afab262c8a72f392
|
4
|
+
data.tar.gz: d8444062fdb0099f152d89285dfe568aae19cb48
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 79400d78724736c4e8a147f7ecb042f1df956b8ace50157baab1be14a9531aa6a892546728a8085cc37b4a93e9376fbdfe3da069ecf23fd744bf6d6e9c64b97f
|
7
|
+
data.tar.gz: 2e70ab743786160758ee287450f59e21946131001663577436e38bfc2361ffd9e6146d661c06dbc9e4eeb5da8ff88bcb4339c752c3523930193e892bc39e07ba
|
data/README
CHANGED
@@ -18,7 +18,9 @@ Install with 'gem install rdf-microdata'
|
|
18
18
|
|
19
19
|
### Living implementation
|
20
20
|
Microdata to RDF transformation is undergoing active development. This implementation attempts to be up-to-date
|
21
|
-
as of the time of release, and is being used in developing the [Microdata RDF][] specification
|
21
|
+
as of the time of release, and is being used in developing the [Microdata RDF][] specification.
|
22
|
+
|
23
|
+
This implementation includes support for the proposed [@itemprop-reverse](https://www.w3.org/wiki/WebSchemas/InverseProperties#Proposed_Action:_New_attribute_.40itemprop-reverse) attribute.
|
22
24
|
|
23
25
|
### Microdata Registry
|
24
26
|
The parser uses a build-in version of the [Microdata RDF][] registry.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.1.
|
1
|
+
1.1.2
|
data/lib/rdf/microdata/reader.rb
CHANGED
@@ -147,6 +147,7 @@ module RDF::Microdata
|
|
147
147
|
|
148
148
|
##
|
149
149
|
# Determine if property should be serialized as a list or not
|
150
|
+
#
|
150
151
|
# @param [RDF::URI] predicateURI
|
151
152
|
# @return [Boolean]
|
152
153
|
def as_list(predicateURI)
|
@@ -161,6 +162,7 @@ module RDF::Microdata
|
|
161
162
|
|
162
163
|
##
|
163
164
|
# Yield a equivalentProperty or subPropertyOf if appropriate
|
165
|
+
#
|
164
166
|
# @param [RDF::URI] predicateURI
|
165
167
|
# @yield statement
|
166
168
|
# @yieldparam [RDF::Statement] statement
|
@@ -311,10 +313,12 @@ module RDF::Microdata
|
|
311
313
|
def node_path(node)
|
312
314
|
"<#{base_uri}>#{node.respond_to?(:display_path) ? node.display_path : node}"
|
313
315
|
end
|
314
|
-
|
316
|
+
|
317
|
+
##
|
315
318
|
# Add debug event to debug array, if specified
|
316
319
|
#
|
317
320
|
# @param [Nokogiri::XML::Node, #to_s] node XML Node or string for showing context
|
321
|
+
#
|
318
322
|
# @param [String] message
|
319
323
|
# @yieldreturn [String] appended to message, to allow for lazy-evaulation of message
|
320
324
|
def add_debug(node, message = "")
|
@@ -329,9 +333,11 @@ module RDF::Microdata
|
|
329
333
|
raise RDF::ReaderError, message if validate?
|
330
334
|
end
|
331
335
|
|
336
|
+
##
|
332
337
|
# add a statement, object can be literal or URI or bnode
|
333
338
|
#
|
334
339
|
# @param [Nokogiri::XML::Node, any] node XML Node or string for showing context
|
340
|
+
#
|
335
341
|
# @param [URI, BNode] subject the subject of the statement
|
336
342
|
# @param [URI] predicate the predicate of the statement
|
337
343
|
# @param [URI, BNode, Literal] object the object of the statement
|
@@ -367,16 +373,14 @@ module RDF::Microdata
|
|
367
373
|
items = []
|
368
374
|
# 1) For each element that is also a top-level item run the following algorithm:
|
369
375
|
#
|
370
|
-
# 1) Generate the triples for an item item, using the evaluation context.
|
371
|
-
# Let result be the (URI reference or blank node) subject returned.
|
376
|
+
# 1) Generate the triples for an item item, using the evaluation context. Let result be the (URI reference or blank node) subject returned.
|
372
377
|
# 2) Append result to item list.
|
373
378
|
getItems.each do |el|
|
374
379
|
result = generate_triples(el, ec)
|
375
380
|
items << result
|
376
381
|
end
|
377
382
|
|
378
|
-
# 2) Generate an RDF Collection list from
|
379
|
-
# the ordered list of values. Set value to the value returned from generate an RDF Collection.
|
383
|
+
# 2) Generate an RDF Collection list from the ordered list of values. Set value to the value returned from generate an RDF Collection.
|
380
384
|
value = generateRDFCollection(root, items)
|
381
385
|
|
382
386
|
# 3) Generate the following triple:
|
@@ -390,6 +394,7 @@ module RDF::Microdata
|
|
390
394
|
|
391
395
|
##
|
392
396
|
# Generate triples for an item
|
397
|
+
#
|
393
398
|
# @param [RDF::Resource] item
|
394
399
|
# @param [Hash{Symbol => Object}] ec
|
395
400
|
# @option ec [Hash{Nokogiri::XML::Element} => RDF::Resource] memory
|
@@ -397,9 +402,7 @@ module RDF::Microdata
|
|
397
402
|
# @return [RDF::Resource]
|
398
403
|
def generate_triples(item, ec = {})
|
399
404
|
memory = ec[:memory]
|
400
|
-
# 1) If there is an entry for item in memory, then let subject be the subject of that entry.
|
401
|
-
# Otherwise, if item has a global identifier and that global identifier is an absolute URL,
|
402
|
-
# let subject be that global identifier. Otherwise, let subject be a new blank node.
|
405
|
+
# 1) If there is an entry for item in memory, then let subject be the subject of that entry. Otherwise, if item has a global identifier and that global identifier is an absolute URL, let subject be that global identifier. Otherwise, let subject be a new blank node.
|
403
406
|
subject = if memory.include?(item.node)
|
404
407
|
memory[item.node][:subject]
|
405
408
|
elsif item.has_attribute?('itemid')
|
@@ -432,8 +435,7 @@ module RDF::Microdata
|
|
432
435
|
add_debug(item) {"gentrips(7): vocab=#{vocab.inspect}"}
|
433
436
|
add_triple(item, base_uri, USES_VOCAB, RDF::URI(vocab.uri)) if vocab
|
434
437
|
|
435
|
-
# 8) Otherwise, if type is not empty, construct vocab by removing everything following the last
|
436
|
-
# SOLIDUS U+002F ("/") or NUMBER SIGN U+0023 ("#") from the path component of type.
|
438
|
+
# 8) Otherwise, if type is not empty, construct vocab by removing everything following the last SOLIDUS U+002F ("/") or NUMBER SIGN U+0023 ("#") from the path component of type.
|
437
439
|
vocab ||= begin
|
438
440
|
type_vocab = type.to_s.sub(/([\/\#])[^\/\#]*$/, '\1')
|
439
441
|
add_debug(item) {"gentrips(8): type_vocab=#{type_vocab.inspect}"}
|
@@ -446,9 +448,7 @@ module RDF::Microdata
|
|
446
448
|
# 10) Set property list to an empty mapping between properties and one or more ordered values as established below.
|
447
449
|
property_list = {}
|
448
450
|
|
449
|
-
# 11. For each element _element_ that has one or more property names and is one of the
|
450
|
-
# properties of the item _item_, in the order those elements are given by the algorithm
|
451
|
-
# that returns the properties of an item, run the following substep:
|
451
|
+
# 11. For each element _element_ that has one or more property names and is one of the properties of the item _item_, in the order those elements are given by the algorithm that returns the properties of an item, run the following substep:
|
452
452
|
props = item_properties(item)
|
453
453
|
# 11.1. For each name name in element's property names, run the following substeps:
|
454
454
|
props.each do |element|
|
@@ -475,8 +475,7 @@ module RDF::Microdata
|
|
475
475
|
value = property_value(element)
|
476
476
|
add_debug(item) {"gentrips(11.1.3) value=#{value.inspect}"}
|
477
477
|
|
478
|
-
# 11.1.4) If value is an item, then generate the triples for value context.
|
479
|
-
# Replace value by the subject returned from those steps.
|
478
|
+
# 11.1.4) If value is an item, then generate the triples for value context. Replace value by the subject returned from those steps.
|
480
479
|
if value.is_a?(Hash)
|
481
480
|
value = generate_triples(element, ec_new)
|
482
481
|
add_debug(item) {"gentrips(11.1.4): value=#{value.inspect}"}
|
@@ -487,7 +486,49 @@ module RDF::Microdata
|
|
487
486
|
property_list[predicate] << value
|
488
487
|
end
|
489
488
|
end
|
490
|
-
|
489
|
+
|
490
|
+
# 11r. For each element _element_ that has one or more property names and is one of the reverse properties of the item _item_, in the order those elements are given by the algorithm that returns the properties of an item, run the following substep:
|
491
|
+
props = item_properties(item, true)
|
492
|
+
# 11r.1. For each name name in element's reverse property names, run the following substeps:
|
493
|
+
props.each do |element|
|
494
|
+
element.attribute('itemprop-reverse').to_s.split(' ').compact.each do |name|
|
495
|
+
add_debug(item) {"gentrips(11r.1): name=#{name.inspect}, type=#{type}"}
|
496
|
+
# 11r.1.1) Let context be a copy of evaluation context with current type set to type and current vocabulary set to vocab.
|
497
|
+
ec_new = ec.merge({:current_type => type, :current_vocabulary => vocab})
|
498
|
+
|
499
|
+
# 11r.1.2) Let predicate be the result of generate predicate URI using context and name. Update context by setting current name to predicate.
|
500
|
+
predicate = vocab.predicateURI(name, ec_new)
|
501
|
+
|
502
|
+
# (Generate Predicate URI steps 6 and 7)
|
503
|
+
vocab.expand(predicate) do |statement|
|
504
|
+
add_debug(item) {
|
505
|
+
"gentrips(11.1.2): expansion #{statement.inspect}"
|
506
|
+
}
|
507
|
+
@callback.call(statement)
|
508
|
+
end
|
509
|
+
|
510
|
+
ec_new[:current_name] = predicate
|
511
|
+
add_debug(item) {"gentrips(11r.1.2): predicate=#{predicate}"}
|
512
|
+
|
513
|
+
# 11r.1.3) Let value be the property value of element.
|
514
|
+
value = property_value(element)
|
515
|
+
add_debug(item) {"gentrips(11r.1.3) value=#{value.inspect}"}
|
516
|
+
|
517
|
+
# 11r.1.4) If value is an item, then generate the triples for value context. Replace value by the subject returned from those steps.
|
518
|
+
if value.is_a?(Hash)
|
519
|
+
value = generate_triples(element, ec_new)
|
520
|
+
add_debug(item) {"gentrips(11.1.4): value=#{value.inspect}"}
|
521
|
+
elsif value.is_a?(RDF::Literal)
|
522
|
+
# 11r.1.4r) Otherwise, if value is a literal, ignore the value and continue to the next name; it is an error for the value of @itemprop-reverse to be a literal
|
523
|
+
add_error(element, "Value of @itemprop-reverse may not be a literal: #{value.inspect}")
|
524
|
+
next
|
525
|
+
end
|
526
|
+
|
527
|
+
# 11r.1.5r) Generate a property value using value as the subject and subject as the object
|
528
|
+
generatePropertyValues(item, value, predicate, [subject])
|
529
|
+
end
|
530
|
+
end
|
531
|
+
|
491
532
|
# 12) For each predicate in property list
|
492
533
|
property_list.each do |predicate, values|
|
493
534
|
generatePropertyValues(item, subject, predicate, values)
|
@@ -497,8 +538,7 @@ module RDF::Microdata
|
|
497
538
|
end
|
498
539
|
|
499
540
|
def generatePropertyValues(element, subject, predicate, values)
|
500
|
-
# If the registry contains a URI prefix that is a character for character match of predicate up to the length
|
501
|
-
# of the URI prefix, set vocab as that URI prefix. Otherwise set vocab to null
|
541
|
+
# If the registry contains a URI prefix that is a character for character match of predicate up to the length of the URI prefix, set vocab as that URI prefix. Otherwise set vocab to null
|
502
542
|
registry = Registry.find(predicate)
|
503
543
|
add_debug("generatePropertyValues") { "list(#{predicate})? #{registry.as_list(predicate).inspect}"} if registry
|
504
544
|
if registry && registry.as_list(predicate)
|
@@ -523,17 +563,15 @@ module RDF::Microdata
|
|
523
563
|
end
|
524
564
|
|
525
565
|
##
|
526
|
-
# To find the properties of an item defined by the element root, the user agent must try
|
527
|
-
# to crawl the properties of the element root, with an empty list as the value of memory:
|
528
|
-
# if this fails, then the properties of the item defined by the element root is an empty
|
529
|
-
# list; otherwise, it is the returned list.
|
566
|
+
# To find the properties of an item defined by the element root, the user agent must try to crawl the properties of the element root, with an empty list as the value of memory: if this fails, then the properties of the item defined by the element root is an empty list; otherwise, it is the returned list.
|
530
567
|
#
|
531
568
|
# @param [Nokogiri::XML::Element] item
|
569
|
+
# @param [Boolean] reverse (false) return reverse properties
|
532
570
|
# @return [Array<Nokogiri::XML::Element>]
|
533
571
|
# List of property elements for an item
|
534
|
-
def item_properties(item)
|
535
|
-
add_debug(item, "item_properties")
|
536
|
-
results, errors = crawl_properties(item, [])
|
572
|
+
def item_properties(item, reverse = false)
|
573
|
+
add_debug(item, "item_properties (#{reverse.inspect})")
|
574
|
+
results, errors = crawl_properties(item, [], reverse)
|
537
575
|
raise CrawlFailure, "item_props: errors=#{errors}" if errors > 0
|
538
576
|
results
|
539
577
|
rescue CrawlFailure => e
|
@@ -542,38 +580,34 @@ module RDF::Microdata
|
|
542
580
|
end
|
543
581
|
|
544
582
|
##
|
545
|
-
# To crawl the properties of an element root with a list memory, the user agent must run
|
546
|
-
# the following steps. These steps either fail or return a list with a count of errors.
|
547
|
-
# The count of errors is used as part of the authoring conformance criteria below.
|
583
|
+
# To crawl the properties of an element root with a list memory, the user agent must run the following steps. These steps either fail or return a list with a count of errors. The count of errors is used as part of the authoring conformance criteria below.
|
548
584
|
#
|
549
585
|
# @param [Nokogiri::XML::Element] root
|
550
586
|
# @param [Array<Nokokogiri::XML::Element>] memory
|
587
|
+
# @param [Boolean] reverse crawl reverse properties
|
551
588
|
# @return [Array<Array<Nokogiri::XML::Element>, Integer>]
|
552
589
|
# Resultant elements and error count
|
553
|
-
def crawl_properties(root, memory)
|
590
|
+
def crawl_properties(root, memory, reverse)
|
554
591
|
|
555
592
|
# 1. If root is in memory, then the algorithm fails; abort these steps.
|
556
593
|
raise CrawlFailure, "crawl_props mem already has #{root.inspect}" if memory.include?(root)
|
557
594
|
|
558
|
-
# 2. Collect all the elements in the item root; let results be the resulting
|
559
|
-
# list of elements, and errors be the resulting count of errors.
|
595
|
+
# 2. Collect all the elements in the item root; let results be the resulting list of elements, and errors be the resulting count of errors.
|
560
596
|
results, errors = elements_in_item(root)
|
561
|
-
add_debug(root) {"crawl_properties results=#{results.map {|e| node_path(e)}.inspect}, errors=#{errors}"}
|
597
|
+
add_debug(root) {"crawl_properties reverse=#{reverse.inspect} results=#{results.map {|e| node_path(e)}.inspect}, errors=#{errors}"}
|
562
598
|
|
563
|
-
# 3. Remove any elements from results that do not have an itemprop attribute specified.
|
564
|
-
results = results.select {|e| e.has_attribute?('itemprop')}
|
599
|
+
# 3. Remove any elements from results that do not have an @itemprop (@itemprop-reverse) attribute specified.
|
600
|
+
results = results.select {|e| e.has_attribute?(reverse ? 'itemprop-reverse' : 'itemprop')}
|
565
601
|
|
566
602
|
# 4. Let new memory be a new list consisting of the old list memory with the addition of root.
|
567
603
|
new_memory = memory + [root]
|
568
604
|
|
569
|
-
# 5. For each element in results that has an itemscope attribute specified,
|
570
|
-
# crawl the properties of the element, with new memory as the memory.
|
605
|
+
# 5. For each element in results that has an @itemscope attribute specified, crawl the properties of the element, with new memory as the memory.
|
571
606
|
results.select {|e| e.has_attribute?('itemscope')}.each do |element|
|
572
607
|
begin
|
573
|
-
crawl_properties(element, new_memory)
|
608
|
+
crawl_properties(element, new_memory, reverse)
|
574
609
|
rescue CrawlFailure => e
|
575
|
-
# If this fails, then remove the element from results and increment errors.
|
576
|
-
# (If it succeeds, the return value is discarded.)
|
610
|
+
# If this fails, then remove the element from results and increment errors. (If it succeeds, the return value is discarded.)
|
577
611
|
memory -= element
|
578
612
|
add_error(element, e.message)
|
579
613
|
errors += 1
|
@@ -584,8 +618,7 @@ module RDF::Microdata
|
|
584
618
|
end
|
585
619
|
|
586
620
|
##
|
587
|
-
# To collect all the elements in the item root, the user agent must run these steps.
|
588
|
-
# They return a list of elements and a count of errors.
|
621
|
+
# To collect all the elements in the item root, the user agent must run these steps. They return a list of elements and a count of errors.
|
589
622
|
#
|
590
623
|
# @param [Nokogiri::XML::Element] root
|
591
624
|
# @return [Array<Array<Nokogiri::XML::Element>, Integer>]
|
@@ -616,8 +649,7 @@ module RDF::Microdata
|
|
616
649
|
add_error(current, "elements_in_item: results already includes #{current.inspect}")
|
617
650
|
errors += 1
|
618
651
|
elsif !current.has_attribute?('itemscope')
|
619
|
-
# If current is not already in results and current does not have an itemscope attribute,
|
620
|
-
# then: add all the child elements of current to pending.
|
652
|
+
# If current is not already in results and current does not have an itemscope attribute, then: add all the child elements of current to pending.
|
621
653
|
pending += current.elements
|
622
654
|
end
|
623
655
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rdf-microdata
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gregg
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-08-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rdf
|