rdf_context 0.4.2
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.
- data/.autotest +2 -0
- data/.gitignore +10 -0
- data/.gitmodules +3 -0
- data/History.txt +73 -0
- data/README.rdoc +145 -0
- data/Rakefile +77 -0
- data/VERSION +1 -0
- data/bin/reddy +59 -0
- data/lib/rdf_context.rb +60 -0
- data/lib/rdf_context/bnode.rb +99 -0
- data/lib/rdf_context/conjunctive_graph.rb +47 -0
- data/lib/rdf_context/exceptions.rb +11 -0
- data/lib/rdf_context/graph.rb +333 -0
- data/lib/rdf_context/literal.rb +340 -0
- data/lib/rdf_context/n3_grammar.rb +2171 -0
- data/lib/rdf_context/n3_grammar.treetop +143 -0
- data/lib/rdf_context/n3parser.rb +152 -0
- data/lib/rdf_context/namespace.rb +82 -0
- data/lib/rdf_context/nokogiri_hacks.rb +8 -0
- data/lib/rdf_context/parser.rb +119 -0
- data/lib/rdf_context/rdfaparser.rb +398 -0
- data/lib/rdf_context/rdfxmlparser.rb +525 -0
- data/lib/rdf_context/store/abstract_sql_store.rb +843 -0
- data/lib/rdf_context/store/abstract_store.rb +64 -0
- data/lib/rdf_context/store/list_store.rb +63 -0
- data/lib/rdf_context/store/memory_store.rb +323 -0
- data/lib/rdf_context/store/sqlite3_store.rb +223 -0
- data/lib/rdf_context/string_hacks.rb +108 -0
- data/lib/rdf_context/term_utils.rb +196 -0
- data/lib/rdf_context/triple.rb +144 -0
- data/lib/rdf_context/uriref.rb +95 -0
- data/script/console +10 -0
- data/spec/bnode_spec.rb +58 -0
- data/spec/conjunctive_graph_spec.rb +60 -0
- data/spec/graph_spec.rb +390 -0
- data/spec/list_store_spec.rb +12 -0
- data/spec/literal_spec.rb +314 -0
- data/spec/matchers.rb +150 -0
- data/spec/memory_store_spec.rb +23 -0
- data/spec/n3parser_spec.rb +229 -0
- data/spec/namespaces_spec.rb +66 -0
- data/spec/ntriples/test.nt +78 -0
- data/spec/parser_spec.rb +29 -0
- data/spec/rdfa-triples/0001.nt +1 -0
- data/spec/rdfa-triples/0006.nt +2 -0
- data/spec/rdfa-triples/0007.nt +3 -0
- data/spec/rdfa-triples/0008.nt +1 -0
- data/spec/rdfa-triples/0009.nt +1 -0
- data/spec/rdfa-triples/0010.nt +2 -0
- data/spec/rdfa-triples/0011.nt +3 -0
- data/spec/rdfa-triples/0012.nt +1 -0
- data/spec/rdfa-triples/0013.nt +1 -0
- data/spec/rdfa-triples/0014.nt +1 -0
- data/spec/rdfa-triples/0015.nt +2 -0
- data/spec/rdfa-triples/0017.nt +3 -0
- data/spec/rdfa-triples/0018.nt +1 -0
- data/spec/rdfa-triples/0019.nt +1 -0
- data/spec/rdfa-triples/0020.nt +1 -0
- data/spec/rdfa-triples/0021.nt +1 -0
- data/spec/rdfa-triples/0023.nt +1 -0
- data/spec/rdfa-triples/0025.nt +2 -0
- data/spec/rdfa-triples/0026.nt +1 -0
- data/spec/rdfa-triples/0027.nt +1 -0
- data/spec/rdfa-triples/0029.nt +1 -0
- data/spec/rdfa-triples/0030.nt +1 -0
- data/spec/rdfa-triples/0031.nt +1 -0
- data/spec/rdfa-triples/0032.nt +1 -0
- data/spec/rdfa-triples/0033.nt +2 -0
- data/spec/rdfa-triples/0034.nt +1 -0
- data/spec/rdfa-triples/0035.nt +1 -0
- data/spec/rdfa-triples/0036.nt +1 -0
- data/spec/rdfa-triples/0037.nt +1 -0
- data/spec/rdfa-triples/0038.nt +1 -0
- data/spec/rdfa-triples/0039.nt +1 -0
- data/spec/rdfa-triples/0040.nt +1 -0
- data/spec/rdfa-triples/0041.nt +1 -0
- data/spec/rdfa-triples/0042.nt +0 -0
- data/spec/rdfa-triples/0046.nt +3 -0
- data/spec/rdfa-triples/0047.nt +3 -0
- data/spec/rdfa-triples/0048.nt +3 -0
- data/spec/rdfa-triples/0049.nt +2 -0
- data/spec/rdfa-triples/0050.nt +2 -0
- data/spec/rdfa-triples/0051.nt +2 -0
- data/spec/rdfa-triples/0052.nt +1 -0
- data/spec/rdfa-triples/0053.nt +2 -0
- data/spec/rdfa-triples/0054.nt +2 -0
- data/spec/rdfa-triples/0055.nt +2 -0
- data/spec/rdfa-triples/0056.nt +3 -0
- data/spec/rdfa-triples/0057.nt +4 -0
- data/spec/rdfa-triples/0058.nt +6 -0
- data/spec/rdfa-triples/0059.nt +6 -0
- data/spec/rdfa-triples/0060.nt +2 -0
- data/spec/rdfa-triples/0061.nt +1 -0
- data/spec/rdfa-triples/0062.nt +1 -0
- data/spec/rdfa-triples/0063.nt +1 -0
- data/spec/rdfa-triples/0064.nt +1 -0
- data/spec/rdfa-triples/0065.nt +3 -0
- data/spec/rdfa-triples/0066.nt +1 -0
- data/spec/rdfa-triples/0067.nt +1 -0
- data/spec/rdfa-triples/0068.nt +1 -0
- data/spec/rdfa-triples/0069.nt +1 -0
- data/spec/rdfa-triples/0070.nt +1 -0
- data/spec/rdfa-triples/0071.nt +1 -0
- data/spec/rdfa-triples/0072.nt +1 -0
- data/spec/rdfa-triples/0073.nt +1 -0
- data/spec/rdfa-triples/0074.nt +1 -0
- data/spec/rdfa-triples/0075.nt +1 -0
- data/spec/rdfa-triples/0076.nt +23 -0
- data/spec/rdfa-triples/0077.nt +23 -0
- data/spec/rdfa-triples/0078.nt +6 -0
- data/spec/rdfa-triples/0079.nt +3 -0
- data/spec/rdfa-triples/0080.nt +1 -0
- data/spec/rdfa-triples/0081.nt +6 -0
- data/spec/rdfa-triples/0082.nt +8 -0
- data/spec/rdfa-triples/0083.nt +6 -0
- data/spec/rdfa-triples/0084.nt +8 -0
- data/spec/rdfa-triples/0085.nt +4 -0
- data/spec/rdfa-triples/0086.nt +0 -0
- data/spec/rdfa-triples/0087.nt +23 -0
- data/spec/rdfa-triples/0088.nt +3 -0
- data/spec/rdfa-triples/0089.nt +1 -0
- data/spec/rdfa-triples/0090.nt +1 -0
- data/spec/rdfa-triples/0091.nt +3 -0
- data/spec/rdfa-triples/0092.nt +3 -0
- data/spec/rdfa-triples/0093.nt +2 -0
- data/spec/rdfa-triples/0094.nt +3 -0
- data/spec/rdfa-triples/0099.nt +1 -0
- data/spec/rdfa-triples/0100.nt +3 -0
- data/spec/rdfa-triples/0101.nt +3 -0
- data/spec/rdfa-triples/0102.nt +1 -0
- data/spec/rdfa-triples/0103.nt +1 -0
- data/spec/rdfa-triples/0104.nt +3 -0
- data/spec/rdfa-triples/0105.nt +1 -0
- data/spec/rdfa-triples/0106.nt +1 -0
- data/spec/rdfa-triples/0107.nt +0 -0
- data/spec/rdfa-triples/0108.nt +1 -0
- data/spec/rdfa-triples/0109.nt +1 -0
- data/spec/rdfa-triples/0110.nt +1 -0
- data/spec/rdfa-triples/0111.nt +2 -0
- data/spec/rdfa-triples/0112.nt +1 -0
- data/spec/rdfa-triples/0113.nt +2 -0
- data/spec/rdfa-triples/0114.nt +3 -0
- data/spec/rdfa-triples/0115.nt +4 -0
- data/spec/rdfa-triples/0116.nt +2 -0
- data/spec/rdfa-triples/0117.nt +2 -0
- data/spec/rdfa-triples/0118.nt +1 -0
- data/spec/rdfa-triples/0119.nt +1 -0
- data/spec/rdfa-triples/0120.nt +1 -0
- data/spec/rdfa-triples/0121.nt +2 -0
- data/spec/rdfa-triples/0122.nt +1 -0
- data/spec/rdfa-triples/0123.nt +3 -0
- data/spec/rdfa-triples/0124.nt +4 -0
- data/spec/rdfa-triples/0125.nt +1 -0
- data/spec/rdfa-triples/0126.nt +3 -0
- data/spec/rdfa-triples/1001.nt +6 -0
- data/spec/rdfa_helper.rb +189 -0
- data/spec/rdfa_parser_spec.rb +148 -0
- data/spec/rdfcore/Manifest.rdf +5395 -0
- data/spec/rdfcore/amp-in-url/test001.nt +16 -0
- data/spec/rdfcore/amp-in-url/test001.rdf +40 -0
- data/spec/rdfcore/datatypes-intensional/test001.nt +18 -0
- data/spec/rdfcore/datatypes-intensional/test002.nt +18 -0
- data/spec/rdfcore/datatypes/test001.nt +15 -0
- data/spec/rdfcore/datatypes/test001.rdf +29 -0
- data/spec/rdfcore/datatypes/test002.nt +14 -0
- data/spec/rdfcore/datatypes/test002.rdf +27 -0
- data/spec/rdfcore/datatypes/test002b.nt +17 -0
- data/spec/rdfcore/datatypes/test003a.nt +16 -0
- data/spec/rdfcore/datatypes/test003b.nt +16 -0
- data/spec/rdfcore/datatypes/test005a.nt +16 -0
- data/spec/rdfcore/datatypes/test005b.nt +16 -0
- data/spec/rdfcore/datatypes/test006.nt +17 -0
- data/spec/rdfcore/datatypes/test008a.nt +15 -0
- data/spec/rdfcore/datatypes/test008b.nt +15 -0
- data/spec/rdfcore/datatypes/test009a.nt +15 -0
- data/spec/rdfcore/datatypes/test009b.nt +15 -0
- data/spec/rdfcore/datatypes/test010.nt +17 -0
- data/spec/rdfcore/datatypes/test011a.nt +17 -0
- data/spec/rdfcore/datatypes/test011b.nt +17 -0
- data/spec/rdfcore/horst-01/test001.rdf +38 -0
- data/spec/rdfcore/horst-01/test002.rdf +39 -0
- data/spec/rdfcore/horst-01/test003.rdf +40 -0
- data/spec/rdfcore/horst-01/test004.rdf +42 -0
- data/spec/rdfcore/pfps-10/test001a.nt +14 -0
- data/spec/rdfcore/pfps-10/test001b.nt +15 -0
- data/spec/rdfcore/rdf-charmod-literals/test001.nt +15 -0
- data/spec/rdfcore/rdf-charmod-literals/test001.rdf +34 -0
- data/spec/rdfcore/rdf-charmod-uris/test001.nt +14 -0
- data/spec/rdfcore/rdf-charmod-uris/test001.rdf +34 -0
- data/spec/rdfcore/rdf-charmod-uris/test002.nt +15 -0
- data/spec/rdfcore/rdf-charmod-uris/test002.rdf +33 -0
- data/spec/rdfcore/rdf-containers-syntax-vs-schema/error001.rdf +27 -0
- data/spec/rdfcore/rdf-containers-syntax-vs-schema/error002.rdf +34 -0
- data/spec/rdfcore/rdf-containers-syntax-vs-schema/test001.nt +17 -0
- data/spec/rdfcore/rdf-containers-syntax-vs-schema/test001.rdf +27 -0
- data/spec/rdfcore/rdf-containers-syntax-vs-schema/test002.nt +19 -0
- data/spec/rdfcore/rdf-containers-syntax-vs-schema/test002.rdf +37 -0
- data/spec/rdfcore/rdf-containers-syntax-vs-schema/test003.nt +18 -0
- data/spec/rdfcore/rdf-containers-syntax-vs-schema/test003.rdf +29 -0
- data/spec/rdfcore/rdf-containers-syntax-vs-schema/test004.nt +29 -0
- data/spec/rdfcore/rdf-containers-syntax-vs-schema/test004.rdf +33 -0
- data/spec/rdfcore/rdf-containers-syntax-vs-schema/test006.nt +40 -0
- data/spec/rdfcore/rdf-containers-syntax-vs-schema/test006.rdf +28 -0
- data/spec/rdfcore/rdf-containers-syntax-vs-schema/test007.nt +20 -0
- data/spec/rdfcore/rdf-containers-syntax-vs-schema/test007.rdf +32 -0
- data/spec/rdfcore/rdf-containers-syntax-vs-schema/test008.nt +15 -0
- data/spec/rdfcore/rdf-containers-syntax-vs-schema/test008.rdf +28 -0
- data/spec/rdfcore/rdf-element-not-mandatory/test001.nt +10 -0
- data/spec/rdfcore/rdf-element-not-mandatory/test001.rdf +14 -0
- data/spec/rdfcore/rdf-ns-prefix-confusion/test0001.nt +14 -0
- data/spec/rdfcore/rdf-ns-prefix-confusion/test0001.rdf +35 -0
- data/spec/rdfcore/rdf-ns-prefix-confusion/test0003.nt +14 -0
- data/spec/rdfcore/rdf-ns-prefix-confusion/test0003.rdf +35 -0
- data/spec/rdfcore/rdf-ns-prefix-confusion/test0004.nt +14 -0
- data/spec/rdfcore/rdf-ns-prefix-confusion/test0004.rdf +34 -0
- data/spec/rdfcore/rdf-ns-prefix-confusion/test0005.nt +15 -0
- data/spec/rdfcore/rdf-ns-prefix-confusion/test0005.rdf +40 -0
- data/spec/rdfcore/rdf-ns-prefix-confusion/test0006.nt +14 -0
- data/spec/rdfcore/rdf-ns-prefix-confusion/test0006.rdf +32 -0
- data/spec/rdfcore/rdf-ns-prefix-confusion/test0009.nt +14 -0
- data/spec/rdfcore/rdf-ns-prefix-confusion/test0009.rdf +32 -0
- data/spec/rdfcore/rdf-ns-prefix-confusion/test0010.nt +14 -0
- data/spec/rdfcore/rdf-ns-prefix-confusion/test0010.rdf +38 -0
- data/spec/rdfcore/rdf-ns-prefix-confusion/test0011.nt +15 -0
- data/spec/rdfcore/rdf-ns-prefix-confusion/test0011.rdf +40 -0
- data/spec/rdfcore/rdf-ns-prefix-confusion/test0012.nt +15 -0
- data/spec/rdfcore/rdf-ns-prefix-confusion/test0012.rdf +40 -0
- data/spec/rdfcore/rdf-ns-prefix-confusion/test0013.nt +15 -0
- data/spec/rdfcore/rdf-ns-prefix-confusion/test0013.rdf +40 -0
- data/spec/rdfcore/rdf-ns-prefix-confusion/test0014.nt +15 -0
- data/spec/rdfcore/rdf-ns-prefix-confusion/test0014.rdf +42 -0
- data/spec/rdfcore/rdfms-abouteach/error001.rdf +35 -0
- data/spec/rdfcore/rdfms-abouteach/error002.rdf +35 -0
- data/spec/rdfcore/rdfms-difference-between-ID-and-about/error1.rdf +25 -0
- data/spec/rdfcore/rdfms-difference-between-ID-and-about/test1.nt +14 -0
- data/spec/rdfcore/rdfms-difference-between-ID-and-about/test1.rdf +22 -0
- data/spec/rdfcore/rdfms-difference-between-ID-and-about/test2.nt +14 -0
- data/spec/rdfcore/rdfms-difference-between-ID-and-about/test2.rdf +22 -0
- data/spec/rdfcore/rdfms-difference-between-ID-and-about/test3.nt +14 -0
- data/spec/rdfcore/rdfms-difference-between-ID-and-about/test3.rdf +22 -0
- data/spec/rdfcore/rdfms-duplicate-member-props/test001.nt +17 -0
- data/spec/rdfcore/rdfms-duplicate-member-props/test001.rdf +30 -0
- data/spec/rdfcore/rdfms-empty-property-elements/error001.rdf +33 -0
- data/spec/rdfcore/rdfms-empty-property-elements/error002.rdf +33 -0
- data/spec/rdfcore/rdfms-empty-property-elements/error003.rdf +39 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test001.nt +14 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test001.rdf +33 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test002.nt +14 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test002.rdf +31 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test003.nt +14 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test003.rdf +32 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test004.nt +14 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test004.rdf +32 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test005.nt +18 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test005.rdf +32 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test006.nt +18 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test006.rdf +32 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test007.nt +14 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test007.rdf +32 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test008.nt +14 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test008.rdf +31 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test009.nt +14 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test009.rdf +32 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test010.nt +14 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test010.rdf +31 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test011.nt +18 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test011.rdf +30 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test012.nt +18 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test012.rdf +30 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test013.nt +15 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test013.rdf +35 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test014.nt +15 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test014.rdf +34 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test015.nt +15 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test015.rdf +38 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test016.nt +14 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test016.rdf +31 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test017.nt +14 -0
- data/spec/rdfcore/rdfms-empty-property-elements/test017.rdf +38 -0
- data/spec/rdfcore/rdfms-identity-anon-resources/test001.nt +14 -0
- data/spec/rdfcore/rdfms-identity-anon-resources/test001.rdf +33 -0
- data/spec/rdfcore/rdfms-identity-anon-resources/test002.nt +15 -0
- data/spec/rdfcore/rdfms-identity-anon-resources/test002.rdf +33 -0
- data/spec/rdfcore/rdfms-identity-anon-resources/test003.nt +14 -0
- data/spec/rdfcore/rdfms-identity-anon-resources/test003.rdf +31 -0
- data/spec/rdfcore/rdfms-identity-anon-resources/test004.nt +15 -0
- data/spec/rdfcore/rdfms-identity-anon-resources/test004.rdf +33 -0
- data/spec/rdfcore/rdfms-identity-anon-resources/test005.nt +14 -0
- data/spec/rdfcore/rdfms-identity-anon-resources/test005.rdf +31 -0
- data/spec/rdfcore/rdfms-not-id-and-resource-attr/test001.nt +19 -0
- data/spec/rdfcore/rdfms-not-id-and-resource-attr/test001.rdf +29 -0
- data/spec/rdfcore/rdfms-not-id-and-resource-attr/test002.nt +15 -0
- data/spec/rdfcore/rdfms-not-id-and-resource-attr/test002.rdf +29 -0
- data/spec/rdfcore/rdfms-not-id-and-resource-attr/test004.nt +18 -0
- data/spec/rdfcore/rdfms-not-id-and-resource-attr/test004.rdf +29 -0
- data/spec/rdfcore/rdfms-not-id-and-resource-attr/test005.nt +19 -0
- data/spec/rdfcore/rdfms-not-id-and-resource-attr/test005.rdf +29 -0
- data/spec/rdfcore/rdfms-para196/test001.nt +17 -0
- data/spec/rdfcore/rdfms-para196/test001.rdf +35 -0
- data/spec/rdfcore/rdfms-rdf-id/error001.rdf +26 -0
- data/spec/rdfcore/rdfms-rdf-id/error002.rdf +26 -0
- data/spec/rdfcore/rdfms-rdf-id/error003.rdf +29 -0
- data/spec/rdfcore/rdfms-rdf-id/error004.rdf +27 -0
- data/spec/rdfcore/rdfms-rdf-id/error005.rdf +31 -0
- data/spec/rdfcore/rdfms-rdf-id/error006.rdf +26 -0
- data/spec/rdfcore/rdfms-rdf-id/error007.rdf +29 -0
- data/spec/rdfcore/rdfms-rdf-names-use/error-001.rdf +23 -0
- data/spec/rdfcore/rdfms-rdf-names-use/error-002.rdf +23 -0
- data/spec/rdfcore/rdfms-rdf-names-use/error-003.rdf +23 -0
- data/spec/rdfcore/rdfms-rdf-names-use/error-004.rdf +23 -0
- data/spec/rdfcore/rdfms-rdf-names-use/error-005.rdf +23 -0
- data/spec/rdfcore/rdfms-rdf-names-use/error-006.rdf +23 -0
- data/spec/rdfcore/rdfms-rdf-names-use/error-007.rdf +23 -0
- data/spec/rdfcore/rdfms-rdf-names-use/error-008.rdf +23 -0
- data/spec/rdfcore/rdfms-rdf-names-use/error-009.rdf +23 -0
- data/spec/rdfcore/rdfms-rdf-names-use/error-010.rdf +23 -0
- data/spec/rdfcore/rdfms-rdf-names-use/error-011.rdf +25 -0
- data/spec/rdfcore/rdfms-rdf-names-use/error-012.rdf +25 -0
- data/spec/rdfcore/rdfms-rdf-names-use/error-013.rdf +25 -0
- data/spec/rdfcore/rdfms-rdf-names-use/error-014.rdf +25 -0
- data/spec/rdfcore/rdfms-rdf-names-use/error-015.rdf +25 -0
- data/spec/rdfcore/rdfms-rdf-names-use/error-016.rdf +25 -0
- data/spec/rdfcore/rdfms-rdf-names-use/error-017.rdf +25 -0
- data/spec/rdfcore/rdfms-rdf-names-use/error-018.rdf +25 -0
- data/spec/rdfcore/rdfms-rdf-names-use/error-019.rdf +25 -0
- data/spec/rdfcore/rdfms-rdf-names-use/error-020.rdf +25 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-001.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-001.rdf +23 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-002.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-002.rdf +23 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-003.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-003.rdf +23 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-004.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-004.rdf +23 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-005.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-005.rdf +23 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-006.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-006.rdf +23 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-007.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-007.rdf +23 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-008.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-008.rdf +23 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-009.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-009.rdf +23 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-010.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-010.rdf +23 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-011.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-011.rdf +23 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-012.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-012.rdf +23 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-013.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-013.rdf +23 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-014.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-014.rdf +23 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-015.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-015.rdf +23 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-016.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-016.rdf +23 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-017.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-017.rdf +25 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-018.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-018.rdf +25 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-019.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-019.rdf +25 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-020.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-020.rdf +25 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-021.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-021.rdf +25 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-022.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-022.rdf +25 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-023.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-023.rdf +25 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-024.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-024.rdf +25 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-025.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-025.rdf +25 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-026.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-026.rdf +25 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-027.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-027.rdf +25 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-028.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-028.rdf +25 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-029.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-029.rdf +25 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-030.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-030.rdf +25 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-031.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-031.rdf +25 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-032.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-032.rdf +24 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-033.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-033.rdf +24 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-034.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-034.rdf +24 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-035.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-035.rdf +24 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-036.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-036.rdf +24 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-037.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/test-037.rdf +24 -0
- data/spec/rdfcore/rdfms-rdf-names-use/warn-001.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/warn-001.rdf +23 -0
- data/spec/rdfcore/rdfms-rdf-names-use/warn-002.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/warn-002.rdf +25 -0
- data/spec/rdfcore/rdfms-rdf-names-use/warn-003.nt +1 -0
- data/spec/rdfcore/rdfms-rdf-names-use/warn-003.rdf +24 -0
- data/spec/rdfcore/rdfms-reification-required/test001.nt +15 -0
- data/spec/rdfcore/rdfms-reification-required/test001.rdf +29 -0
- data/spec/rdfcore/rdfms-seq-representation/empty.nt +13 -0
- data/spec/rdfcore/rdfms-seq-representation/test001.nt +19 -0
- data/spec/rdfcore/rdfms-seq-representation/test001.rdf +33 -0
- data/spec/rdfcore/rdfms-seq-representation/test002.nt +14 -0
- data/spec/rdfcore/rdfms-seq-representation/test003a.nt +14 -0
- data/spec/rdfcore/rdfms-seq-representation/test003b.nt +14 -0
- data/spec/rdfcore/rdfms-seq-representation/test004.nt +14 -0
- data/spec/rdfcore/rdfms-syntax-incomplete/error001.rdf +26 -0
- data/spec/rdfcore/rdfms-syntax-incomplete/error002.rdf +26 -0
- data/spec/rdfcore/rdfms-syntax-incomplete/error003.rdf +29 -0
- data/spec/rdfcore/rdfms-syntax-incomplete/error004.rdf +25 -0
- data/spec/rdfcore/rdfms-syntax-incomplete/error005.rdf +25 -0
- data/spec/rdfcore/rdfms-syntax-incomplete/error006.rdf +28 -0
- data/spec/rdfcore/rdfms-syntax-incomplete/test001.nt +14 -0
- data/spec/rdfcore/rdfms-syntax-incomplete/test001.rdf +28 -0
- data/spec/rdfcore/rdfms-syntax-incomplete/test002.nt +19 -0
- data/spec/rdfcore/rdfms-syntax-incomplete/test002.rdf +38 -0
- data/spec/rdfcore/rdfms-syntax-incomplete/test003.nt +17 -0
- data/spec/rdfcore/rdfms-syntax-incomplete/test003.rdf +28 -0
- data/spec/rdfcore/rdfms-syntax-incomplete/test004.nt +21 -0
- data/spec/rdfcore/rdfms-syntax-incomplete/test004.rdf +36 -0
- data/spec/rdfcore/rdfms-uri-substructure/error001.nt +18 -0
- data/spec/rdfcore/rdfms-uri-substructure/test001.nt +17 -0
- data/spec/rdfcore/rdfms-uri-substructure/test001.rdf +29 -0
- data/spec/rdfcore/rdfms-xml-literal-namespaces/test001.nt +13 -0
- data/spec/rdfcore/rdfms-xml-literal-namespaces/test001.rdf +33 -0
- data/spec/rdfcore/rdfms-xml-literal-namespaces/test002.nt +14 -0
- data/spec/rdfcore/rdfms-xml-literal-namespaces/test002.rdf +47 -0
- data/spec/rdfcore/rdfms-xmllang/test001.nt +14 -0
- data/spec/rdfcore/rdfms-xmllang/test001.rdf +30 -0
- data/spec/rdfcore/rdfms-xmllang/test002.nt +14 -0
- data/spec/rdfcore/rdfms-xmllang/test002.rdf +29 -0
- data/spec/rdfcore/rdfms-xmllang/test003.nt +14 -0
- data/spec/rdfcore/rdfms-xmllang/test003.rdf +28 -0
- data/spec/rdfcore/rdfms-xmllang/test004.nt +14 -0
- data/spec/rdfcore/rdfms-xmllang/test004.rdf +28 -0
- data/spec/rdfcore/rdfms-xmllang/test005.nt +14 -0
- data/spec/rdfcore/rdfms-xmllang/test005.rdf +28 -0
- data/spec/rdfcore/rdfms-xmllang/test006.nt +14 -0
- data/spec/rdfcore/rdfms-xmllang/test006.rdf +29 -0
- data/spec/rdfcore/rdfms-xmllang/test007a.nt +14 -0
- data/spec/rdfcore/rdfms-xmllang/test007b.nt +14 -0
- data/spec/rdfcore/rdfms-xmllang/test007c.nt +14 -0
- data/spec/rdfcore/rdfs-container-membership-superProperty/not1C.rdf +13 -0
- data/spec/rdfcore/rdfs-container-membership-superProperty/not1P.rdf +14 -0
- data/spec/rdfcore/rdfs-domain-and-range/nonconclusions005.rdf +28 -0
- data/spec/rdfcore/rdfs-domain-and-range/nonconclusions006.rdf +28 -0
- data/spec/rdfcore/rdfs-domain-and-range/premises005.rdf +32 -0
- data/spec/rdfcore/rdfs-domain-and-range/premises006.rdf +32 -0
- data/spec/rdfcore/rdfs-domain-and-range/test001.nt +16 -0
- data/spec/rdfcore/rdfs-domain-and-range/test001.rdf +29 -0
- data/spec/rdfcore/rdfs-domain-and-range/test002.nt +16 -0
- data/spec/rdfcore/rdfs-domain-and-range/test002.rdf +29 -0
- data/spec/rdfcore/rdfs-entailment/test001.nt +16 -0
- data/spec/rdfcore/rdfs-entailment/test002.nt +15 -0
- data/spec/rdfcore/rdfs-no-cycles-in-subClassOf/test001.nt +18 -0
- data/spec/rdfcore/rdfs-no-cycles-in-subClassOf/test001.rdf +37 -0
- data/spec/rdfcore/rdfs-no-cycles-in-subPropertyOf/test001.nt +18 -0
- data/spec/rdfcore/rdfs-no-cycles-in-subPropertyOf/test001.rdf +40 -0
- data/spec/rdfcore/rdfs-subClassOf-a-Property/test001.nt +15 -0
- data/spec/rdfcore/rdfs-subPropertyOf-semantics/test001.nt +24 -0
- data/spec/rdfcore/rdfs-subPropertyOf-semantics/test002.nt +21 -0
- data/spec/rdfcore/statement-entailment/test001a.nt +12 -0
- data/spec/rdfcore/statement-entailment/test001b.nt +2 -0
- data/spec/rdfcore/statement-entailment/test002a.nt +2 -0
- data/spec/rdfcore/statement-entailment/test002b.nt +5 -0
- data/spec/rdfcore/tex-01/test001.rdf +34 -0
- data/spec/rdfcore/tex-01/test002.rdf +33 -0
- data/spec/rdfcore/unrecognised-xml-attributes/test001.nt +15 -0
- data/spec/rdfcore/unrecognised-xml-attributes/test001.rdf +31 -0
- data/spec/rdfcore/unrecognised-xml-attributes/test002.nt +14 -0
- data/spec/rdfcore/unrecognised-xml-attributes/test002.rdf +32 -0
- data/spec/rdfcore/xml-canon/test001.nt +16 -0
- data/spec/rdfcore/xml-canon/test001.rdf +28 -0
- data/spec/rdfcore/xmlbase/test001.nt +14 -0
- data/spec/rdfcore/xmlbase/test001.rdf +27 -0
- data/spec/rdfcore/xmlbase/test002.nt +14 -0
- data/spec/rdfcore/xmlbase/test002.rdf +28 -0
- data/spec/rdfcore/xmlbase/test003.nt +14 -0
- data/spec/rdfcore/xmlbase/test003.rdf +25 -0
- data/spec/rdfcore/xmlbase/test004.nt +18 -0
- data/spec/rdfcore/xmlbase/test004.rdf +27 -0
- data/spec/rdfcore/xmlbase/test006.nt +15 -0
- data/spec/rdfcore/xmlbase/test006.rdf +26 -0
- data/spec/rdfcore/xmlbase/test007.nt +14 -0
- data/spec/rdfcore/xmlbase/test007.rdf +25 -0
- data/spec/rdfcore/xmlbase/test008.nt +14 -0
- data/spec/rdfcore/xmlbase/test008.rdf +25 -0
- data/spec/rdfcore/xmlbase/test009.nt +14 -0
- data/spec/rdfcore/xmlbase/test009.rdf +26 -0
- data/spec/rdfcore/xmlbase/test010.nt +14 -0
- data/spec/rdfcore/xmlbase/test010.rdf +26 -0
- data/spec/rdfcore/xmlbase/test011.nt +14 -0
- data/spec/rdfcore/xmlbase/test011.rdf +27 -0
- data/spec/rdfcore/xmlbase/test013.nt +15 -0
- data/spec/rdfcore/xmlbase/test013.rdf +28 -0
- data/spec/rdfcore/xmlbase/test014.nt +15 -0
- data/spec/rdfcore/xmlbase/test014.rdf +28 -0
- data/spec/rdfcore/xmlsch-02/test001.rdf +34 -0
- data/spec/rdfcore/xmlsch-02/test002.rdf +34 -0
- data/spec/rdfcore/xmlsch-02/test003.rdf +37 -0
- data/spec/rdfxml_helper.rb +137 -0
- data/spec/rdfxml_spec.rb +362 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/sqlite3_store_spec.rb +41 -0
- data/spec/store_helper.rb +231 -0
- data/spec/string_hacks_spec.rb +21 -0
- data/spec/triple_spec.rb +172 -0
- data/spec/uriref_spec.rb +117 -0
- data/test/longtests_spec.rb +25 -0
- data/test/n3_tests/lcsh/sh85062913.n3 +41 -0
- data/test/n3_tests/lcsh/sh85062913.nt +21 -0
- data/test/n3_tests/lcsh/sh85082139.n3 +157 -0
- data/test/n3_tests/lcsh/sh85082139.nt +79 -0
- data/test/n3_tests/lcsh/sh85118553.n3 +123 -0
- data/test/n3_tests/lcsh/sh85118553.nt +63 -0
- data/test/n3_tests/misc/on_now-01.n3 +30 -0
- data/test/n3_tests/misc/on_now-01.nt +15 -0
- data/test/n3_tests/n3p/simple-01.n3 +1 -0
- data/test/n3_tests/n3p/simple-01.nt +0 -0
- data/test/n3_tests/n3p/simple-02.n3 +4 -0
- data/test/n3_tests/n3p/simple-02.nt +0 -0
- data/test/n3_tests/n3p/simple-03.n3 +5 -0
- data/test/n3_tests/n3p/simple-03.nt +1 -0
- data/test/n3_tests/n3p/simple-04.n3 +6 -0
- data/test/n3_tests/n3p/simple-04.nt +3 -0
- data/test/n3_tests/n3p/simple-05.n3 +7 -0
- data/test/n3_tests/n3p/simple-05.nt +2 -0
- data/test/n3_tests/n3p/simple-06.n3 +6 -0
- data/test/n3_tests/n3p/simple-06.nt +4 -0
- data/test/n3_tests/n3p/simple-07.n3 +7 -0
- data/test/n3_tests/n3p/simple-07.nt +6 -0
- data/test/perf_test/test.rb +11 -0
- data/test/perf_test/tommorris.rdf +2267 -0
- data/test/rdf_tests/cc197bad-dc9c-440d-a5b5-d52ba2e14234.nt +24 -0
- data/test/rdf_tests/cc197bad-dc9c-440d-a5b5-d52ba2e14234.rdf +46 -0
- data/test/rdf_tests/tm_001.nt +1 -0
- data/test/rdf_tests/tm_001.rdf +7 -0
- data/test/rdf_tests/xml-literal-mixed.nt +7 -0
- data/test/rdf_tests/xml-literal-mixed.rdf +15 -0
- data/test/xml.rdf +6 -0
- metadata +696 -0
@@ -0,0 +1,398 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'parser')
|
2
|
+
|
3
|
+
module RdfContext
|
4
|
+
##
|
5
|
+
# An RDFa parser in Ruby
|
6
|
+
#
|
7
|
+
# Based on processing rules described here: http://www.w3.org/TR/rdfa-syntax/#s_model
|
8
|
+
#
|
9
|
+
# Ben Adida
|
10
|
+
# 2008-05-07
|
11
|
+
# Gregg Kellogg
|
12
|
+
# 2009-08-04
|
13
|
+
class RdfaParser < Parser
|
14
|
+
attr_reader :namespace
|
15
|
+
|
16
|
+
# The Recursive Baggage
|
17
|
+
class EvaluationContext # :nodoc:
|
18
|
+
attr :base, true
|
19
|
+
attr :parent_subject, true
|
20
|
+
attr :parent_object, true
|
21
|
+
attr :uri_mappings, true
|
22
|
+
attr :incomplete_triples, true
|
23
|
+
attr :language, true
|
24
|
+
|
25
|
+
def initialize(base)
|
26
|
+
# Initialize the evaluation context, [5.1]
|
27
|
+
@base = base
|
28
|
+
@parent_subject = @base
|
29
|
+
@parent_object = nil
|
30
|
+
@uri_mappings = {}
|
31
|
+
@incomplete_triples = []
|
32
|
+
@language = nil
|
33
|
+
end
|
34
|
+
|
35
|
+
# Copy this Evaluation Context
|
36
|
+
def initialize_copy(from)
|
37
|
+
# clone the evaluation context correctly
|
38
|
+
@uri_mappings = from.uri_mappings.clone
|
39
|
+
@incomplete_triples = from.incomplete_triples.clone
|
40
|
+
end
|
41
|
+
|
42
|
+
def inspect
|
43
|
+
v = %w(base parent_subject parent_object language).map {|a| "#{a}='#{self.send(a).nil? ? 'nil' : self.send(a)}'"}
|
44
|
+
v << "uri_mappings[#{uri_mappings.keys.length}]"
|
45
|
+
v << "incomplete_triples[#{incomplete_triples.length}]"
|
46
|
+
v.join(",")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Parse XHTML+RDFa document from a string or input stream to closure or graph.
|
51
|
+
#
|
52
|
+
# Optionally, the stream may be a Nokogiri::HTML::Document or Nokogiri::XML::Document
|
53
|
+
# With a block, yeilds each statement with URIRef, BNode or Literal elements
|
54
|
+
#
|
55
|
+
# @param [IO] stream:: the HTML+RDFa IO stream, string, Nokogiri::HTML::Document or Nokogiri::XML::Document
|
56
|
+
# @param [String] uri:: the URI of the document
|
57
|
+
# @param [Hash] options:: Parser options, one of
|
58
|
+
# <em>options[:debug]</em>:: Array to place debug messages
|
59
|
+
# <em>options[:strict]</em>:: Raise Error if true, continue with lax parsing, otherwise
|
60
|
+
# @return [Graph]:: Returns the graph containing parsed triples
|
61
|
+
# @raise [Error]:: Raises RdfError if _strict_
|
62
|
+
def parse(stream, uri = nil, options = {}, &block) # :yields: triple
|
63
|
+
super
|
64
|
+
|
65
|
+
@doc = case stream
|
66
|
+
when Nokogiri::HTML::Document then stream
|
67
|
+
when Nokogiri::XML::Document then stream
|
68
|
+
else Nokogiri::XML.parse(stream, uri)
|
69
|
+
end
|
70
|
+
|
71
|
+
raise ParserException, "Empty document" if @doc.nil? && @strict
|
72
|
+
@callback = block
|
73
|
+
|
74
|
+
# If the doc has a default, use that as "html"
|
75
|
+
ns = @doc.namespaces["xmlns"]
|
76
|
+
ns ||= "http://www.w3.org/1999/xhtml" # FIXME: intuite from DOCTYPE, or however
|
77
|
+
@namespace = Namespace.new(ns, "html") if ns
|
78
|
+
|
79
|
+
# parse
|
80
|
+
parse_whole_document(@doc, @uri)
|
81
|
+
|
82
|
+
@graph
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
# Parsing an RDFa document (this is *not* the recursive method)
|
88
|
+
def parse_whole_document(doc, base)
|
89
|
+
# find if the document has a base element
|
90
|
+
base_el = doc.css('html>head>base').first
|
91
|
+
if (base_el)
|
92
|
+
base = base_el.attributes['href']
|
93
|
+
# Strip any fragment from base
|
94
|
+
base = base.to_s.split("#").first
|
95
|
+
add_debug(base_el, "parse_whole_doc: base='#{base}'")
|
96
|
+
end
|
97
|
+
|
98
|
+
# initialize the evaluation context with the appropriate base
|
99
|
+
evaluation_context= EvaluationContext.new(base)
|
100
|
+
|
101
|
+
traverse(doc.root, evaluation_context)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Extract the XMLNS mappings from an element
|
105
|
+
def extract_mappings(element)
|
106
|
+
mappings = {}
|
107
|
+
|
108
|
+
# look for xmlns
|
109
|
+
element.namespaces.each do |attr_name,attr_value|
|
110
|
+
begin
|
111
|
+
abbr, suffix = attr_name.split(":")
|
112
|
+
mappings[suffix] = @graph.bind(Namespace.new(attr_value, suffix)) if abbr == "xmlns"
|
113
|
+
rescue RdfException => e
|
114
|
+
add_debug(element, "extract_mappings raised #{e.class}: #{e.message}")
|
115
|
+
raise if @strict
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
add_debug(element, "mappings: #{mappings.keys.join(", ")}")
|
120
|
+
mappings
|
121
|
+
end
|
122
|
+
|
123
|
+
# The recursive helper function
|
124
|
+
def traverse(element, evaluation_context)
|
125
|
+
if element.nil?
|
126
|
+
add_debug(element, "traverse nil element")
|
127
|
+
raise ParserException, "Can't parse nil element" if @strict
|
128
|
+
return nil
|
129
|
+
end
|
130
|
+
|
131
|
+
# local variables [5.5 Step 1]
|
132
|
+
recurse = true
|
133
|
+
skip = false
|
134
|
+
new_subject = nil
|
135
|
+
current_object_resource = nil
|
136
|
+
uri_mappings = evaluation_context.uri_mappings.clone
|
137
|
+
incomplete_triples = []
|
138
|
+
language = evaluation_context.language
|
139
|
+
|
140
|
+
# shortcut
|
141
|
+
attrs = element.attributes
|
142
|
+
|
143
|
+
about = attrs['about']
|
144
|
+
src = attrs['src']
|
145
|
+
resource = attrs['resource']
|
146
|
+
href = attrs['href']
|
147
|
+
|
148
|
+
# Pull out the attributes needed for the skip test.
|
149
|
+
property = attrs['property'].to_s if attrs['property']
|
150
|
+
typeof = attrs['typeof'].to_s if attrs['typeof']
|
151
|
+
datatype = attrs['datatype'].to_s if attrs['datatype']
|
152
|
+
content = attrs['content'].to_s if attrs['content']
|
153
|
+
rel = attrs['rel'].to_s if attrs['rel']
|
154
|
+
rev = attrs['rev'].to_s if attrs['rev']
|
155
|
+
|
156
|
+
# SPEC CONFUSION: not sure what to initialize this value to
|
157
|
+
current_object_literal = nil
|
158
|
+
|
159
|
+
# XMLNS mappings [5.5 Step 2]
|
160
|
+
uri_mappings.merge!(extract_mappings(element))
|
161
|
+
|
162
|
+
# Language information [5.5 Step 3]
|
163
|
+
add_debug(element, "traverse, lang: #{attrs['lang']}") if attrs['lang']
|
164
|
+
language = attrs['lang'] || language
|
165
|
+
|
166
|
+
# rels and revs
|
167
|
+
rels = parse_curies(rel, uri_mappings, evaluation_context.base, true)
|
168
|
+
revs = parse_curies(rev, uri_mappings, evaluation_context.base, true)
|
169
|
+
valid_rel_or_rev = !(rel.nil? && rev.nil?)
|
170
|
+
|
171
|
+
add_debug(element, "traverse, ec: #{evaluation_context.inspect}")
|
172
|
+
add_debug(element, "traverse, about: #{about.nil? ? 'nil' : about}, src: #{src.nil? ? 'nil' : src}, resource: #{resource.nil? ? 'nil' : resource}, href: #{href.nil? ? 'nil' : href}")
|
173
|
+
add_debug(element, "traverse, property: #{property.nil? ? 'nil' : property}, typeof: #{typeof.nil? ? 'nil' : typeof}, datatype: #{datatype.nil? ? 'nil' : datatype}, content: #{content.nil? ? 'nil' : content}")
|
174
|
+
add_debug(element, "traverse, rels: #{rels.join(" ")}, revs: #{revs.join(" ")}")
|
175
|
+
|
176
|
+
if not valid_rel_or_rev
|
177
|
+
# Establishing a new subject if no valid rel/rev [5.5 Step 4]
|
178
|
+
if about
|
179
|
+
new_subject = uri_or_safe_curie(about, evaluation_context, uri_mappings)
|
180
|
+
elsif src
|
181
|
+
new_subject = URIRef.new(src, evaluation_context.base)
|
182
|
+
elsif resource
|
183
|
+
new_subject = uri_or_safe_curie(resource, evaluation_context, uri_mappings)
|
184
|
+
elsif href
|
185
|
+
new_subject = URIRef.new(href, evaluation_context.base)
|
186
|
+
end
|
187
|
+
|
188
|
+
# SPEC CONFUSION: not sure what "If no URI is provided by a resource attribute" means, I assume
|
189
|
+
# it means that new_subject is still null
|
190
|
+
if new_subject.nil?
|
191
|
+
if element.name =~ /^(head|body)$/ && evaluation_context.base
|
192
|
+
new_subject = URIRef.new(evaluation_context.base)
|
193
|
+
elsif element.attributes['typeof']
|
194
|
+
new_subject = BNode.new
|
195
|
+
else
|
196
|
+
# if it's null, it's null and nothing changes
|
197
|
+
new_subject = evaluation_context.parent_object
|
198
|
+
skip = true unless property
|
199
|
+
end
|
200
|
+
end
|
201
|
+
add_debug(element, "new_subject: #{new_subject}, skip = #{skip}")
|
202
|
+
else
|
203
|
+
# Establish both new subject and current object resource [5.5 Step 5]
|
204
|
+
|
205
|
+
if about
|
206
|
+
new_subject = uri_or_safe_curie(about, evaluation_context, uri_mappings)
|
207
|
+
elsif src
|
208
|
+
new_subject = uri_or_safe_curie(src, evaluation_context, uri_mappings)
|
209
|
+
end
|
210
|
+
|
211
|
+
# If no URI is provided then the first match from the following rules will apply
|
212
|
+
if new_subject.nil?
|
213
|
+
if element.name =~ /^(head|body)$/
|
214
|
+
new_subject = URIRef.new(evaluation_context.base)
|
215
|
+
elsif element.attributes['typeof']
|
216
|
+
new_subject = BNode.new
|
217
|
+
else
|
218
|
+
# if it's null, it's null and nothing changes
|
219
|
+
new_subject = evaluation_context.parent_object
|
220
|
+
# no skip flag set this time
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
if resource
|
225
|
+
current_object_resource = uri_or_safe_curie(resource, evaluation_context, uri_mappings)
|
226
|
+
elsif href
|
227
|
+
current_object_resource = URIRef.new(href, evaluation_context.base)
|
228
|
+
end
|
229
|
+
|
230
|
+
add_debug(element, "new_subject: #{new_subject}, current_object_resource = #{current_object_resource.nil? ? 'nil' : current_object_resource}")
|
231
|
+
end
|
232
|
+
|
233
|
+
# Process @typeof if there is a subject [Step 6]
|
234
|
+
if new_subject and typeof
|
235
|
+
types = parse_curies(typeof, uri_mappings, evaluation_context.base, false)
|
236
|
+
add_debug(element, "typeof: #{typeof}")
|
237
|
+
types.each do |one_type|
|
238
|
+
add_triple(element, new_subject, RDF_TYPE, one_type)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
# Generate triples with given object [Step 7]
|
243
|
+
if current_object_resource
|
244
|
+
rels.each do |rel|
|
245
|
+
add_triple(element, new_subject, rel, current_object_resource)
|
246
|
+
end
|
247
|
+
|
248
|
+
revs.each do |rev|
|
249
|
+
add_triple(element, current_object_resource, rev, new_subject)
|
250
|
+
end
|
251
|
+
else
|
252
|
+
# Incomplete triples and bnode creation [Step 8]
|
253
|
+
add_debug(element, "step 8: valid: #{valid_rel_or_rev}, rels: #{rels}, revs: #{revs}")
|
254
|
+
current_object_resource = BNode.new if valid_rel_or_rev
|
255
|
+
|
256
|
+
rels.each do |rel|
|
257
|
+
# SPEC CONFUSION: we don't store the subject here?
|
258
|
+
incomplete_triples << {:predicate => rel, :direction => :forward}
|
259
|
+
end
|
260
|
+
|
261
|
+
revs.each do |rev|
|
262
|
+
# SPEC CONFUSION: we don't store the object here?
|
263
|
+
incomplete_triples << {:predicate => rev, :direction => :reverse}
|
264
|
+
end
|
265
|
+
|
266
|
+
end
|
267
|
+
|
268
|
+
# Establish current object literal [Step 9]
|
269
|
+
if property
|
270
|
+
properties = parse_curies(property, uri_mappings, evaluation_context.base, false)
|
271
|
+
|
272
|
+
# get the literal datatype
|
273
|
+
type = datatype
|
274
|
+
children_node_types = element.children.collect{|c| c.class}.uniq
|
275
|
+
|
276
|
+
# the following 3 IF clauses should be mutually exclusive. Written as is to prevent extensive indentation.
|
277
|
+
|
278
|
+
# SPEC CONFUSION: have to special case XML Literal, not clear right away.
|
279
|
+
# SPEC CONFUSION: specify that the conditions are in order of priority
|
280
|
+
type_resource = curie_to_resource_or_bnode(type, uri_mappings, evaluation_context.base) if type
|
281
|
+
if type and !type.empty? and (type_resource.to_s != XML_LITERAL.to_s)
|
282
|
+
# typed literal
|
283
|
+
add_debug(element, "typed literal")
|
284
|
+
current_object_literal = Literal.typed(content || element.inner_text, type_resource, :language => language)
|
285
|
+
elsif content or (children_node_types == [Nokogiri::XML::Text]) or (element.children.length == 0) or (type == '')
|
286
|
+
# plain literal
|
287
|
+
add_debug(element, "plain literal")
|
288
|
+
current_object_literal = Literal.untyped(content || element.inner_text, language)
|
289
|
+
elsif children_node_types != [Nokogiri::XML::Text] and (type == nil or type_resource.to_s == XML_LITERAL.to_s)
|
290
|
+
# XML Literal
|
291
|
+
add_debug(element, "XML Literal: #{element.inner_html}")
|
292
|
+
current_object_literal = Literal.typed(element.children, XML_LITERAL, :language => language, :namespaces => uri_mappings)
|
293
|
+
recurse = false
|
294
|
+
end
|
295
|
+
|
296
|
+
# add each property
|
297
|
+
properties.each do |property|
|
298
|
+
add_triple(element, new_subject, property, current_object_literal)
|
299
|
+
end
|
300
|
+
|
301
|
+
# SPEC CONFUSION: "the triple has been created" ==> there may be more than one
|
302
|
+
# set the recurse flag above in the IF about xmlliteral, as it is the only place that can happen
|
303
|
+
end
|
304
|
+
|
305
|
+
# Complete the incomplete triples from the evaluation context [Step 10]
|
306
|
+
add_debug(element, "10: skip=#{skip}, new_subject=#{new_subject}")
|
307
|
+
if not skip and new_subject
|
308
|
+
evaluation_context.incomplete_triples.each do |trip|
|
309
|
+
if trip[:direction] == :forward
|
310
|
+
add_triple(element, evaluation_context.parent_subject, trip[:predicate], new_subject)
|
311
|
+
elsif trip[:direction] == :reverse
|
312
|
+
add_triple(element, new_subject, trip[:predicate], evaluation_context.parent_subject)
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
# Create a new evaluation context and proceed recursively [Step 11]
|
318
|
+
if recurse
|
319
|
+
# SPEC CONFUSION: new evaluation context for each child? Probably not necessary,
|
320
|
+
# but maybe needs to be pointed out?
|
321
|
+
|
322
|
+
if skip
|
323
|
+
new_ec = evaluation_context.clone
|
324
|
+
new_ec.language = language
|
325
|
+
new_ec.uri_mappings = uri_mappings
|
326
|
+
add_debug(element, "skip: cloned ec: #{evaluation_context.inspect}")
|
327
|
+
else
|
328
|
+
# create a new evaluation context
|
329
|
+
new_ec = EvaluationContext.new(evaluation_context.base)
|
330
|
+
new_ec.parent_subject = new_subject || evaluation_context.parent_subject
|
331
|
+
new_ec.parent_object = current_object_resource || new_subject || evaluation_context.parent_subject
|
332
|
+
new_ec.uri_mappings = uri_mappings
|
333
|
+
new_ec.incomplete_triples = incomplete_triples
|
334
|
+
new_ec.language = language
|
335
|
+
#add_debug(element, "new ec: #{new_ec.inspect}")
|
336
|
+
end
|
337
|
+
|
338
|
+
element.children.each do |child|
|
339
|
+
# recurse only if it's an element
|
340
|
+
traverse(child, new_ec) if child.class == Nokogiri::XML::Element
|
341
|
+
end
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
# space-separated CURIEs or Link Types
|
346
|
+
def parse_curies(value, uri_mappings, base, with_link_types=false)
|
347
|
+
return [] unless value
|
348
|
+
resource_array = []
|
349
|
+
value.to_s.split(' ').each do |curie|
|
350
|
+
if curie.include?(":")
|
351
|
+
resource_array << curie_to_resource_or_bnode(curie, uri_mappings, base)
|
352
|
+
elsif with_link_types
|
353
|
+
# Reserved words are all mapped to lower case
|
354
|
+
curie = curie.to_s.downcase
|
355
|
+
link_type_curie = curie_to_resource_or_bnode(":#{curie}", XH_MAPPING, base) if LINK_TYPES.include?(curie)
|
356
|
+
resource_array << link_type_curie if link_type_curie
|
357
|
+
end
|
358
|
+
end
|
359
|
+
resource_array
|
360
|
+
end
|
361
|
+
|
362
|
+
def curie_to_resource_or_bnode(curie, uri_mappings, subject)
|
363
|
+
# URI mappings for CURIEs default to XH_MAPPING, rather than the default doc namespace
|
364
|
+
uri_mappings = uri_mappings.merge(XH_MAPPING)
|
365
|
+
prefix, suffix = curie.to_s.split(":")
|
366
|
+
|
367
|
+
# consider the bnode situation
|
368
|
+
if prefix == "_"
|
369
|
+
# we force a non-nil name, otherwise it generates a new name
|
370
|
+
BNode.new(suffix || "", @named_bnodes)
|
371
|
+
elsif curie.to_s.empty?
|
372
|
+
add_debug(nil, "curie_to_resource_or_bnode #{URIRef.new(subject)}")
|
373
|
+
# Empty curie resolves to current subject (No, an empty curie should be ignored)
|
374
|
+
# URIRef.new(subject)
|
375
|
+
nil
|
376
|
+
else
|
377
|
+
ns = uri_mappings[prefix.to_s]
|
378
|
+
unless ns
|
379
|
+
add_debug(nil, "curie_to_resource_or_bnode No namespace mapping for #{prefix}")
|
380
|
+
raise ParserException, "No namespace mapping for #{prefix}" if @strict
|
381
|
+
return nil
|
382
|
+
end
|
383
|
+
ns + suffix
|
384
|
+
end
|
385
|
+
end
|
386
|
+
|
387
|
+
def uri_or_safe_curie(value, evaluation_context, uri_mappings)
|
388
|
+
return nil if value.nil?
|
389
|
+
|
390
|
+
# check if the value is [foo:bar]
|
391
|
+
if value.to_s.match(/^\[(.*)\]$/)
|
392
|
+
curie_to_resource_or_bnode($1, uri_mappings, evaluation_context.parent_subject)
|
393
|
+
else
|
394
|
+
URIRef.new(value, evaluation_context.base)
|
395
|
+
end
|
396
|
+
end
|
397
|
+
end
|
398
|
+
end
|
@@ -0,0 +1,525 @@
|
|
1
|
+
require 'xml'
|
2
|
+
require File.join(File.dirname(__FILE__), 'parser')
|
3
|
+
|
4
|
+
module RdfContext
|
5
|
+
class RdfXmlParser < Parser
|
6
|
+
CORE_SYNTAX_TERMS = %w(RDF ID about parseType resource nodeID datatype).map {|n| "http://www.w3.org/1999/02/22-rdf-syntax-ns##{n}"}
|
7
|
+
OLD_TERMS = %w(aboutEach aboutEachPrefix bagID).map {|n| "http://www.w3.org/1999/02/22-rdf-syntax-ns##{n}"}
|
8
|
+
|
9
|
+
# The Recursive Baggage
|
10
|
+
class EvaluationContext # :nodoc:
|
11
|
+
attr_reader :base
|
12
|
+
attr :subject, true
|
13
|
+
attr :uri_mappings, true
|
14
|
+
attr :language, true
|
15
|
+
attr :graph, true
|
16
|
+
attr :li_counter, true
|
17
|
+
|
18
|
+
def initialize(base, element, graph)
|
19
|
+
# Initialize the evaluation context, [5.1]
|
20
|
+
self.base = base
|
21
|
+
@uri_mappings = {}
|
22
|
+
@language = nil
|
23
|
+
@graph = graph
|
24
|
+
@li_counter = 0
|
25
|
+
@uri_mappings = {}
|
26
|
+
|
27
|
+
extract_from_element(element) if element
|
28
|
+
end
|
29
|
+
|
30
|
+
# Clone existing evaluation context adding information from element
|
31
|
+
def clone(element, options = {})
|
32
|
+
new_ec = EvaluationContext.new(@base, nil, @graph)
|
33
|
+
new_ec.uri_mappings = self.uri_mappings.clone
|
34
|
+
new_ec.language = self.language
|
35
|
+
|
36
|
+
new_ec.extract_from_element(element) if element
|
37
|
+
|
38
|
+
options.each_pair {|k, v| new_ec.send("#{k}=", v)}
|
39
|
+
new_ec
|
40
|
+
end
|
41
|
+
|
42
|
+
# Extract Evaluation Context from an element by looking at ancestors recurively
|
43
|
+
def extract_from_ancestors(el)
|
44
|
+
ancestors = el.ancestors
|
45
|
+
while ancestors.length > 0
|
46
|
+
a = ancestors.pop
|
47
|
+
next unless a.element?
|
48
|
+
extract_from_element(a)
|
49
|
+
end
|
50
|
+
extract_from_element(el)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Extract Evaluation Context from an element
|
54
|
+
def extract_from_element(el)
|
55
|
+
b = el.attribute_with_ns("base", XML_NS.uri.to_s)
|
56
|
+
lang = el.attribute_with_ns("lang", XML_NS.uri.to_s)
|
57
|
+
self.base = URIRef.new(b, self.base) if b
|
58
|
+
self.language = lang if lang
|
59
|
+
self.uri_mappings.merge!(extract_mappings(el))
|
60
|
+
end
|
61
|
+
|
62
|
+
# Extract the XMLNS mappings from an element
|
63
|
+
def extract_mappings(element)
|
64
|
+
mappings = {}
|
65
|
+
|
66
|
+
# look for xmlns
|
67
|
+
element.namespaces.each do |attr_name,attr_value|
|
68
|
+
abbr, suffix = attr_name.to_s.split(":")
|
69
|
+
if abbr == "xmlns"
|
70
|
+
mappings[suffix] = Namespace.new(attr_value, suffix)
|
71
|
+
@graph.bind(mappings[suffix])
|
72
|
+
end
|
73
|
+
end
|
74
|
+
mappings
|
75
|
+
end
|
76
|
+
|
77
|
+
# Produce the next list entry for this context
|
78
|
+
def li_next(predicate)
|
79
|
+
@li_counter += 1
|
80
|
+
predicate = Addressable::URI.parse(predicate.to_s)
|
81
|
+
predicate.fragment = "_#{@li_counter}"
|
82
|
+
predicate = URIRef.new(predicate)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Set XML base. Ignore any fragment
|
86
|
+
def base=(b)
|
87
|
+
b = Addressable::URI.parse(b.to_s)
|
88
|
+
b.fragment = nil
|
89
|
+
@base = b.to_s
|
90
|
+
end
|
91
|
+
|
92
|
+
def inspect
|
93
|
+
v = %w(base subject language).map {|a| "#{a}='#{self.send(a).nil? ? 'nil' : self.send(a)}'"}
|
94
|
+
v << "uri_mappings[#{uri_mappings.keys.length}]"
|
95
|
+
v.join(",")
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Parse RDF/XML document from a string or input stream to closure or graph.
|
100
|
+
#
|
101
|
+
# Optionally, the stream may be a string or Nokogiri::XML::Document
|
102
|
+
# With a block, yeilds each statement with URIRef, BNode or Literal elements
|
103
|
+
#
|
104
|
+
# @param [IO] stream:: the RDF/XML IO stream, string or Nokogiri::XML::Document
|
105
|
+
# @param [String] uri:: the URI of the document
|
106
|
+
# @param [Hash] options:: Parser options, one of
|
107
|
+
# <em>options[:debug]</em>:: Array to place debug messages
|
108
|
+
# <em>options[:strict]</em>:: Raise Error if true, continue with lax parsing, otherwise
|
109
|
+
# @return [Graph]:: Returns the graph containing parsed triples
|
110
|
+
# @raise [Error]:: Raises RdfError if _strict_
|
111
|
+
def parse(stream, uri = nil, options = {}, &block) # :yields: triple
|
112
|
+
super
|
113
|
+
|
114
|
+
@doc = case stream
|
115
|
+
when Nokogiri::XML::Document then stream
|
116
|
+
else Nokogiri::XML.parse(stream, uri)
|
117
|
+
end
|
118
|
+
|
119
|
+
@id_mapping = Hash.new
|
120
|
+
|
121
|
+
raise ParserException, "Empty document" if @doc.nil? && @strict
|
122
|
+
@callback = block
|
123
|
+
|
124
|
+
root = @doc.root
|
125
|
+
|
126
|
+
# Look for rdf:RDF elements and process each.
|
127
|
+
rdf_nodes = root.xpath("//rdf:RDF", RDF_NS.prefix => RDF_NS.uri.to_s)
|
128
|
+
if rdf_nodes.length == 0
|
129
|
+
# If none found, root element may be processed as an RDF Node
|
130
|
+
|
131
|
+
ec = EvaluationContext.new(@uri, root, @graph)
|
132
|
+
nodeElement(root, ec)
|
133
|
+
else
|
134
|
+
rdf_nodes.each do |node|
|
135
|
+
# XXX Skip this element if it's contained within another rdf:RDF element
|
136
|
+
|
137
|
+
# Extract base, lang and namespaces from parents to create proper evaluation context
|
138
|
+
ec = EvaluationContext.new(@uri, nil, @graph)
|
139
|
+
ec.extract_from_ancestors(node)
|
140
|
+
node.children.each {|el|
|
141
|
+
next unless el.elem?
|
142
|
+
new_ec = ec.clone(el)
|
143
|
+
nodeElement(el, new_ec)
|
144
|
+
}
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
@graph
|
149
|
+
end
|
150
|
+
|
151
|
+
private
|
152
|
+
# Is the node rdf:RDF?
|
153
|
+
def is_rdf_root? (node)
|
154
|
+
node.name == "RDF" && node.namespace.href == RDF_NS.uri.to_s
|
155
|
+
end
|
156
|
+
|
157
|
+
# XML nodeElement production
|
158
|
+
#
|
159
|
+
# @param [XML Element] el:: XMl Element to parse
|
160
|
+
# @param [EvaluationContext] ec:: Evaluation context
|
161
|
+
# @return [URIRef] subject:: The subject found for the node
|
162
|
+
# @raise [RdfException]:: Raises Exception if _strict_
|
163
|
+
def nodeElement(el, ec)
|
164
|
+
# subject
|
165
|
+
subject = ec.subject || parse_subject(el, ec)
|
166
|
+
|
167
|
+
add_debug(el, "nodeElement, ec: #{ec.inspect}")
|
168
|
+
add_debug(el, "nodeElement, el: #{el.uri}")
|
169
|
+
add_debug(el, "nodeElement, subject: #{subject.nil? ? 'nil' : subject.to_s}")
|
170
|
+
|
171
|
+
unless el.uri == RDF_NS.Description.to_s
|
172
|
+
add_triple(el, subject, RDF_TYPE, el.uri)
|
173
|
+
end
|
174
|
+
|
175
|
+
# produce triples for attributes
|
176
|
+
el.attribute_nodes.each do |attr|
|
177
|
+
add_debug(el, "propertyAttr: #{attr.uri}='#{attr.value}'")
|
178
|
+
if attr.uri == RDF_TYPE
|
179
|
+
# If there is an attribute a in propertyAttr with a.URI == rdf:type
|
180
|
+
# then u:=uri(identifier:=resolve(a.string-value))
|
181
|
+
# and the following tiple is added to the graph:
|
182
|
+
u = URIRef.new(attr.value, ec.base)
|
183
|
+
add_triple(attr, subject, RDF_TYPE, u)
|
184
|
+
elsif is_propertyAttr?(attr)
|
185
|
+
# Attributes not RDF_TYPE
|
186
|
+
predicate = attr.uri
|
187
|
+
lit = Literal.untyped(attr.value, ec.language)
|
188
|
+
add_triple(attr, subject, predicate, lit)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
# Handle the propertyEltList children events in document order
|
193
|
+
li_counter = 0 # this will increase for each li we iterate through
|
194
|
+
el.children.each do |child|
|
195
|
+
next unless child.elem?
|
196
|
+
child_ec = ec.clone(child)
|
197
|
+
predicate = child.uri
|
198
|
+
add_debug(child, "propertyElt, predicate: #{predicate}")
|
199
|
+
propertyElementURI_check(child)
|
200
|
+
|
201
|
+
# Determine the content type of this property element
|
202
|
+
text_nodes = child.children.select {|e| e.text? && !e.blank?}
|
203
|
+
element_nodes = child.children.select(&:element?)
|
204
|
+
|
205
|
+
# List expansion
|
206
|
+
predicate = ec.li_next(predicate) if predicate == RDF_NS.li
|
207
|
+
|
208
|
+
# Productions based on set of attributes
|
209
|
+
|
210
|
+
# All remaining reserved XML Names (See Name in XML 1.0) are now removed from the set.
|
211
|
+
# These are, all attribute information items in the set with property [prefix] beginning with xml
|
212
|
+
# (case independent comparison) and all attribute information items with [prefix] property having
|
213
|
+
# no value and which have [local name] beginning with xml (case independent comparison) are removed.
|
214
|
+
# Note that the [base URI] accessor is computed by XML Base before any xml:base attribute information item
|
215
|
+
# is deleted.
|
216
|
+
attrs = {}
|
217
|
+
id = datatype = parseType = resourceAttr = nodeID = nil
|
218
|
+
|
219
|
+
child.attribute_nodes.each do |attr|
|
220
|
+
if attr.namespace.to_s.empty?
|
221
|
+
# The support for a limited set of non-namespaced names is REQUIRED and intended to allow
|
222
|
+
# RDF/XML documents specified in [RDF-MS] to remain valid;
|
223
|
+
# new documents SHOULD NOT use these unqualified attributes and applications
|
224
|
+
# MAY choose to warn when the unqualified form is seen in a document.
|
225
|
+
add_debug(el, "Unqualified attribute '#{attr}'")
|
226
|
+
#attrs[attr.to_s] = attr.value unless attr.to_s.match?(/^xml/)
|
227
|
+
elsif attr.namespace.href == XML_NS.uri.to_s
|
228
|
+
# No production. Lang and base elements already extracted
|
229
|
+
elsif attr.namespace.href == RDF_NS.uri.to_s
|
230
|
+
case attr.name
|
231
|
+
when "ID" then id = attr.value
|
232
|
+
when "datatype" then datatype = attr.value
|
233
|
+
when "parseType" then parseType = attr.value
|
234
|
+
when "resource" then resourceAttr = attr.value
|
235
|
+
when "nodeID" then nodeID = attr.value
|
236
|
+
else attrs[attr] = attr.value
|
237
|
+
end
|
238
|
+
else
|
239
|
+
attrs[attr] = attr.value
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
if nodeID && resourceAttr
|
244
|
+
add_debug(el, "Cannot have rdf:nodeID and rdf:resource.")
|
245
|
+
raise ParserException.new("Cannot have rdf:nodeID and rdf:resource.") if @strict
|
246
|
+
end
|
247
|
+
|
248
|
+
# Apply character transformations
|
249
|
+
id = id_check(el, id.rdf_escape, nil) if id
|
250
|
+
resourceAttr = resourceAttr.rdf_escape if resourceAttr
|
251
|
+
nodeID = nodeID_check(el, nodeID.rdf_escape) if nodeID
|
252
|
+
|
253
|
+
add_debug(el, "attrs: #{attrs.inspect}")
|
254
|
+
add_debug(el, "datatype: #{datatype}") if datatype
|
255
|
+
add_debug(el, "parseType: #{parseType}") if parseType
|
256
|
+
add_debug(el, "resource: #{resourceAttr}") if resourceAttr
|
257
|
+
add_debug(el, "nodeID: #{nodeID}") if nodeID
|
258
|
+
add_debug(el, "id: #{id}") if id
|
259
|
+
|
260
|
+
if attrs.empty? && datatype.nil? && parseType.nil? && element_nodes.length == 1
|
261
|
+
# Production resourcePropertyElt
|
262
|
+
|
263
|
+
new_ec = child_ec.clone(nil)
|
264
|
+
new_node_element = element_nodes.first
|
265
|
+
add_debug(child, "resourcePropertyElt: #{node_path(new_node_element)}")
|
266
|
+
new_subject = nodeElement(new_node_element, new_ec)
|
267
|
+
add_triple(child, subject, predicate, new_subject)
|
268
|
+
elsif attrs.empty? && parseType.nil? && element_nodes.length == 0 && text_nodes.length > 0
|
269
|
+
# Production literalPropertyElt
|
270
|
+
add_debug(child, "literalPropertyElt")
|
271
|
+
|
272
|
+
literal = datatype ? Literal.typed(child.inner_html, datatype) : Literal.untyped(child.inner_html, child_ec.language)
|
273
|
+
add_triple(child, subject, predicate, literal)
|
274
|
+
reify(id, child, subject, predicate, literal, ec) if id
|
275
|
+
elsif parseType == "Resource"
|
276
|
+
# Production parseTypeResourcePropertyElt
|
277
|
+
add_debug(child, "parseTypeResourcePropertyElt")
|
278
|
+
|
279
|
+
unless attrs.empty?
|
280
|
+
warn = "Resource Property with extra attributes: '#{attrs.inspect}'"
|
281
|
+
add_debug(child, warn)
|
282
|
+
raise ParserException.new(warn) if @strict
|
283
|
+
end
|
284
|
+
|
285
|
+
# For element e with possibly empty element content c.
|
286
|
+
n = BNode.new
|
287
|
+
add_triple(child, subject, predicate, n)
|
288
|
+
|
289
|
+
# Reification
|
290
|
+
reify(id, child, subject, predicate, n, child_ec) if id
|
291
|
+
|
292
|
+
# If the element content c is not empty, then use event n to create a new sequence of events as follows:
|
293
|
+
#
|
294
|
+
# start-element(URI := rdf:Description,
|
295
|
+
# subject := n,
|
296
|
+
# attributes := set())
|
297
|
+
# c
|
298
|
+
# end-element()
|
299
|
+
add_debug(child, "compose new sequence with rdf:Description")
|
300
|
+
node = child.clone
|
301
|
+
pt_attr = node.attribute("parseType")
|
302
|
+
node.namespace = pt_attr.namespace
|
303
|
+
node.attributes.keys.each {|a| node.remove_attribute(a)}
|
304
|
+
node.node_name = "Description"
|
305
|
+
new_ec = child_ec.clone(nil, :subject => n)
|
306
|
+
nodeElement(node, new_ec)
|
307
|
+
elsif parseType == "Collection"
|
308
|
+
# Production parseTypeCollectionPropertyElt
|
309
|
+
add_debug(child, "parseTypeCollectionPropertyElt")
|
310
|
+
|
311
|
+
unless attrs.empty?
|
312
|
+
warn = "Resource Property with extra attributes: '#{attrs.inspect}'"
|
313
|
+
add_debug(child, warn)
|
314
|
+
raise ParserException.new(warn) if @strict
|
315
|
+
end
|
316
|
+
|
317
|
+
# For element event e with possibly empty nodeElementList l. Set s:=list().
|
318
|
+
# For each element event f in l, n := bnodeid(identifier := generated-blank-node-id()) and append n to s to give a sequence of events.
|
319
|
+
s = element_nodes.map { BNode.new }
|
320
|
+
n = s.first || RDF_NS.send("nil")
|
321
|
+
add_triple(child, subject, predicate, n)
|
322
|
+
reify(id, child, subject, predicate, n, child_ec) if id
|
323
|
+
|
324
|
+
# Add first/rest entries for all list elements
|
325
|
+
s.each_index do |i|
|
326
|
+
n = s[i]
|
327
|
+
o = s[i+1]
|
328
|
+
f = element_nodes[i]
|
329
|
+
|
330
|
+
new_ec = child_ec.clone(nil)
|
331
|
+
object = nodeElement(f, new_ec)
|
332
|
+
add_triple(child, n, RDF_NS.first, object)
|
333
|
+
add_triple(child, n, RDF_NS.rest, o ? o : RDF_NS.nil)
|
334
|
+
end
|
335
|
+
elsif parseType # Literal or Other
|
336
|
+
# Production parseTypeResourcePropertyElt
|
337
|
+
add_debug(child, parseType == "Literal" ? "parseTypeResourcePropertyElt" : "parseTypeOtherPropertyElt (#{parseType})")
|
338
|
+
|
339
|
+
unless attrs.empty?
|
340
|
+
warn = "Resource Property with extra attributes: '#{attrs.inspect}'"
|
341
|
+
add_debug(child, warn)
|
342
|
+
raise ParserException.new(warn) if @strict
|
343
|
+
end
|
344
|
+
|
345
|
+
if resourceAttr
|
346
|
+
warn = "illegal rdf:resource"
|
347
|
+
add_debug(child, warn)
|
348
|
+
raise ParserException.new(warn) if @strict
|
349
|
+
end
|
350
|
+
|
351
|
+
object = Literal.typed(child.children, XML_LITERAL, :namespaces => child_ec.uri_mappings)
|
352
|
+
add_triple(child, subject, predicate, object)
|
353
|
+
elsif text_nodes.length == 0 && element_nodes.length == 0
|
354
|
+
# Production emptyPropertyElt
|
355
|
+
add_debug(child, "emptyPropertyElt")
|
356
|
+
|
357
|
+
if attrs.empty? && resourceAttr.nil? && nodeID.nil?
|
358
|
+
literal = Literal.untyped("", ec.language)
|
359
|
+
add_triple(child, subject, predicate, literal)
|
360
|
+
|
361
|
+
# Reification
|
362
|
+
reify(id, child, subject, predicate, literal, child_ec) if id
|
363
|
+
else
|
364
|
+
if resourceAttr
|
365
|
+
resource = URIRef.new(resourceAttr, ec.base)
|
366
|
+
elsif nodeID
|
367
|
+
resource = BNode.new(nodeID, @named_bnodes)
|
368
|
+
else
|
369
|
+
resource = BNode.new
|
370
|
+
end
|
371
|
+
|
372
|
+
# produce triples for attributes
|
373
|
+
attrs.each_pair do |attr, val|
|
374
|
+
add_debug(el, "attr: #{attr.name}='#{val}'")
|
375
|
+
|
376
|
+
if attr.uri.to_s == RDF_TYPE
|
377
|
+
add_triple(child, resource, RDF_TYPE, val)
|
378
|
+
else
|
379
|
+
# Check for illegal attributes
|
380
|
+
next unless is_propertyAttr?(attr)
|
381
|
+
|
382
|
+
# Attributes not in RDF_TYPE
|
383
|
+
lit = Literal.untyped(val, child_ec.language)
|
384
|
+
add_triple(child, resource, attr.uri.to_s, lit)
|
385
|
+
end
|
386
|
+
end
|
387
|
+
add_triple(child, subject, predicate, resource)
|
388
|
+
|
389
|
+
# Reification
|
390
|
+
reify(id, child, subject, predicate, resource, child_ec) if id
|
391
|
+
end
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
# Return subject
|
396
|
+
subject
|
397
|
+
end
|
398
|
+
|
399
|
+
private
|
400
|
+
# Reify subject, predicate, and object given the EvaluationContext (ec) and current XMl element (el)
|
401
|
+
def reify(id, el, subject, predicate, object, ec)
|
402
|
+
add_debug(el, "reify, id: #{id}")
|
403
|
+
rsubject = URIRef.new("#" + id, ec.base)
|
404
|
+
add_triple(el, rsubject, RDF_NS.subject, subject)
|
405
|
+
add_triple(el, rsubject, RDF_NS.predicate, predicate)
|
406
|
+
add_triple(el, rsubject, RDF_NS.object, object)
|
407
|
+
add_triple(el, rsubject, RDF_TYPE, RDF_NS.Statement)
|
408
|
+
end
|
409
|
+
|
410
|
+
# Figure out the subject from the element.
|
411
|
+
def parse_subject(el, ec)
|
412
|
+
old_property_check(el)
|
413
|
+
|
414
|
+
nodeElementURI_check(el)
|
415
|
+
about = el.attribute("about")
|
416
|
+
id = el.attribute("ID")
|
417
|
+
nodeID = el.attribute("nodeID")
|
418
|
+
|
419
|
+
if nodeID && about
|
420
|
+
add_debug(el, "Cannot have rdf:nodeID and rdf:about.")
|
421
|
+
raise ParserException.new("Cannot have rdf:nodeID and rdf:about.") if @strict
|
422
|
+
elsif nodeID && id
|
423
|
+
add_debug(el, "Cannot have rdf:nodeID and rdf:ID.")
|
424
|
+
raise ParserException.new("Cannot have rdf:nodeID and rdf:ID.") if @strict
|
425
|
+
end
|
426
|
+
|
427
|
+
case
|
428
|
+
when id
|
429
|
+
add_debug(el, "parse_subject, id: '#{id.value.rdf_escape}'")
|
430
|
+
id_check(el, id.value.rdf_escape, ec.base) # Returns URI
|
431
|
+
when nodeID
|
432
|
+
# The value of rdf:nodeID must match the XML Name production
|
433
|
+
nodeID = nodeID_check(el, nodeID.value.rdf_escape)
|
434
|
+
add_debug(el, "parse_subject, nodeID: '#{nodeID}")
|
435
|
+
BNode.new(nodeID, @named_bnodes)
|
436
|
+
when about
|
437
|
+
about = about.value.rdf_escape
|
438
|
+
add_debug(el, "parse_subject, about: '#{about}'")
|
439
|
+
URIRef.new(about, ec.base)
|
440
|
+
else
|
441
|
+
add_debug(el, "parse_subject, BNode")
|
442
|
+
BNode.new
|
443
|
+
end
|
444
|
+
end
|
445
|
+
|
446
|
+
# ID attribute must be an NCName
|
447
|
+
def id_check(el, id, base)
|
448
|
+
if NC_REGEXP.match(id)
|
449
|
+
# ID may only be specified once for the same URI
|
450
|
+
if base
|
451
|
+
uri = URIRef.new("##{id}", base)
|
452
|
+
if @id_mapping[id] && @id_mapping[id] == uri
|
453
|
+
warn = "ID addtribute '#{id}' may only be defined once for the same URI"
|
454
|
+
add_debug(el, warn)
|
455
|
+
raise RdfContext::ParserException.new(warn) if @strict
|
456
|
+
end
|
457
|
+
|
458
|
+
@id_mapping[id] = uri
|
459
|
+
# Returns URI, in this case
|
460
|
+
else
|
461
|
+
id
|
462
|
+
end
|
463
|
+
else
|
464
|
+
warn = "ID addtribute '#{id}' must be a NCName"
|
465
|
+
add_debug(el, "ID addtribute '#{id}' must be a NCName")
|
466
|
+
add_debug(el, warn)
|
467
|
+
raise RdfContext::ParserException.new(warn) if @strict
|
468
|
+
nil
|
469
|
+
end
|
470
|
+
end
|
471
|
+
|
472
|
+
# nodeID must be an XML Name
|
473
|
+
# nodeID must pass Production rdf-id
|
474
|
+
def nodeID_check(el, nodeID)
|
475
|
+
if NC_REGEXP.match(nodeID)
|
476
|
+
nodeID
|
477
|
+
else
|
478
|
+
add_debug(el, "nodeID addtribute '#{nodeID}' must be an XML Name")
|
479
|
+
raise RdfContext::ParserException.new("nodeID addtribute '#{nodeID}' must be a NCName") if @strict
|
480
|
+
nil
|
481
|
+
end
|
482
|
+
end
|
483
|
+
|
484
|
+
# Is this attribute a Property Attribute?
|
485
|
+
def is_propertyAttr?(attr)
|
486
|
+
if ([RDF_NS.Description.to_s, RDF_NS.li.to_s] + OLD_TERMS).include?(attr.uri.to_s)
|
487
|
+
warn = "Invalid use of rdf:#{attr.name}"
|
488
|
+
add_debug(attr, warn)
|
489
|
+
raise InvalidPredicate.new(warn) if @strict
|
490
|
+
return false
|
491
|
+
end
|
492
|
+
!CORE_SYNTAX_TERMS.include?(attr.uri.to_s) &&
|
493
|
+
attr.namespace.href != XML_NS.uri.to_s
|
494
|
+
end
|
495
|
+
|
496
|
+
# Check Node Element name
|
497
|
+
def nodeElementURI_check(el)
|
498
|
+
if (CORE_SYNTAX_TERMS + [RDF_NS.li.to_s] + OLD_TERMS).include?(el.uri.to_s)
|
499
|
+
warn = "Invalid use of rdf:#{el.name}"
|
500
|
+
add_debug(el, warn)
|
501
|
+
raise InvalidSubject.new(warn) if @strict
|
502
|
+
end
|
503
|
+
end
|
504
|
+
|
505
|
+
# Check Property Element name
|
506
|
+
def propertyElementURI_check(el)
|
507
|
+
if (CORE_SYNTAX_TERMS + [RDF_NS.Description.to_s] + OLD_TERMS).include?(el.uri.to_s)
|
508
|
+
warn = "Invalid use of rdf:#{el.name}"
|
509
|
+
add_debug(el, warn)
|
510
|
+
raise InvalidPredicate.new(warn) if @strict
|
511
|
+
end
|
512
|
+
end
|
513
|
+
|
514
|
+
# Check for the use of an obsolete RDF property
|
515
|
+
def old_property_check(el)
|
516
|
+
el.attribute_nodes.each do |attr|
|
517
|
+
if OLD_TERMS.include?(attr.uri.to_s)
|
518
|
+
add_debug(el, "Obsolete attribute '#{attr.uri}'")
|
519
|
+
raise InvalidPredicate.new("Obsolete attribute '#{attr.uri}'") if @strict
|
520
|
+
end
|
521
|
+
end
|
522
|
+
end
|
523
|
+
|
524
|
+
end
|
525
|
+
end
|