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.
Files changed (551) hide show
  1. data/.autotest +2 -0
  2. data/.gitignore +10 -0
  3. data/.gitmodules +3 -0
  4. data/History.txt +73 -0
  5. data/README.rdoc +145 -0
  6. data/Rakefile +77 -0
  7. data/VERSION +1 -0
  8. data/bin/reddy +59 -0
  9. data/lib/rdf_context.rb +60 -0
  10. data/lib/rdf_context/bnode.rb +99 -0
  11. data/lib/rdf_context/conjunctive_graph.rb +47 -0
  12. data/lib/rdf_context/exceptions.rb +11 -0
  13. data/lib/rdf_context/graph.rb +333 -0
  14. data/lib/rdf_context/literal.rb +340 -0
  15. data/lib/rdf_context/n3_grammar.rb +2171 -0
  16. data/lib/rdf_context/n3_grammar.treetop +143 -0
  17. data/lib/rdf_context/n3parser.rb +152 -0
  18. data/lib/rdf_context/namespace.rb +82 -0
  19. data/lib/rdf_context/nokogiri_hacks.rb +8 -0
  20. data/lib/rdf_context/parser.rb +119 -0
  21. data/lib/rdf_context/rdfaparser.rb +398 -0
  22. data/lib/rdf_context/rdfxmlparser.rb +525 -0
  23. data/lib/rdf_context/store/abstract_sql_store.rb +843 -0
  24. data/lib/rdf_context/store/abstract_store.rb +64 -0
  25. data/lib/rdf_context/store/list_store.rb +63 -0
  26. data/lib/rdf_context/store/memory_store.rb +323 -0
  27. data/lib/rdf_context/store/sqlite3_store.rb +223 -0
  28. data/lib/rdf_context/string_hacks.rb +108 -0
  29. data/lib/rdf_context/term_utils.rb +196 -0
  30. data/lib/rdf_context/triple.rb +144 -0
  31. data/lib/rdf_context/uriref.rb +95 -0
  32. data/script/console +10 -0
  33. data/spec/bnode_spec.rb +58 -0
  34. data/spec/conjunctive_graph_spec.rb +60 -0
  35. data/spec/graph_spec.rb +390 -0
  36. data/spec/list_store_spec.rb +12 -0
  37. data/spec/literal_spec.rb +314 -0
  38. data/spec/matchers.rb +150 -0
  39. data/spec/memory_store_spec.rb +23 -0
  40. data/spec/n3parser_spec.rb +229 -0
  41. data/spec/namespaces_spec.rb +66 -0
  42. data/spec/ntriples/test.nt +78 -0
  43. data/spec/parser_spec.rb +29 -0
  44. data/spec/rdfa-triples/0001.nt +1 -0
  45. data/spec/rdfa-triples/0006.nt +2 -0
  46. data/spec/rdfa-triples/0007.nt +3 -0
  47. data/spec/rdfa-triples/0008.nt +1 -0
  48. data/spec/rdfa-triples/0009.nt +1 -0
  49. data/spec/rdfa-triples/0010.nt +2 -0
  50. data/spec/rdfa-triples/0011.nt +3 -0
  51. data/spec/rdfa-triples/0012.nt +1 -0
  52. data/spec/rdfa-triples/0013.nt +1 -0
  53. data/spec/rdfa-triples/0014.nt +1 -0
  54. data/spec/rdfa-triples/0015.nt +2 -0
  55. data/spec/rdfa-triples/0017.nt +3 -0
  56. data/spec/rdfa-triples/0018.nt +1 -0
  57. data/spec/rdfa-triples/0019.nt +1 -0
  58. data/spec/rdfa-triples/0020.nt +1 -0
  59. data/spec/rdfa-triples/0021.nt +1 -0
  60. data/spec/rdfa-triples/0023.nt +1 -0
  61. data/spec/rdfa-triples/0025.nt +2 -0
  62. data/spec/rdfa-triples/0026.nt +1 -0
  63. data/spec/rdfa-triples/0027.nt +1 -0
  64. data/spec/rdfa-triples/0029.nt +1 -0
  65. data/spec/rdfa-triples/0030.nt +1 -0
  66. data/spec/rdfa-triples/0031.nt +1 -0
  67. data/spec/rdfa-triples/0032.nt +1 -0
  68. data/spec/rdfa-triples/0033.nt +2 -0
  69. data/spec/rdfa-triples/0034.nt +1 -0
  70. data/spec/rdfa-triples/0035.nt +1 -0
  71. data/spec/rdfa-triples/0036.nt +1 -0
  72. data/spec/rdfa-triples/0037.nt +1 -0
  73. data/spec/rdfa-triples/0038.nt +1 -0
  74. data/spec/rdfa-triples/0039.nt +1 -0
  75. data/spec/rdfa-triples/0040.nt +1 -0
  76. data/spec/rdfa-triples/0041.nt +1 -0
  77. data/spec/rdfa-triples/0042.nt +0 -0
  78. data/spec/rdfa-triples/0046.nt +3 -0
  79. data/spec/rdfa-triples/0047.nt +3 -0
  80. data/spec/rdfa-triples/0048.nt +3 -0
  81. data/spec/rdfa-triples/0049.nt +2 -0
  82. data/spec/rdfa-triples/0050.nt +2 -0
  83. data/spec/rdfa-triples/0051.nt +2 -0
  84. data/spec/rdfa-triples/0052.nt +1 -0
  85. data/spec/rdfa-triples/0053.nt +2 -0
  86. data/spec/rdfa-triples/0054.nt +2 -0
  87. data/spec/rdfa-triples/0055.nt +2 -0
  88. data/spec/rdfa-triples/0056.nt +3 -0
  89. data/spec/rdfa-triples/0057.nt +4 -0
  90. data/spec/rdfa-triples/0058.nt +6 -0
  91. data/spec/rdfa-triples/0059.nt +6 -0
  92. data/spec/rdfa-triples/0060.nt +2 -0
  93. data/spec/rdfa-triples/0061.nt +1 -0
  94. data/spec/rdfa-triples/0062.nt +1 -0
  95. data/spec/rdfa-triples/0063.nt +1 -0
  96. data/spec/rdfa-triples/0064.nt +1 -0
  97. data/spec/rdfa-triples/0065.nt +3 -0
  98. data/spec/rdfa-triples/0066.nt +1 -0
  99. data/spec/rdfa-triples/0067.nt +1 -0
  100. data/spec/rdfa-triples/0068.nt +1 -0
  101. data/spec/rdfa-triples/0069.nt +1 -0
  102. data/spec/rdfa-triples/0070.nt +1 -0
  103. data/spec/rdfa-triples/0071.nt +1 -0
  104. data/spec/rdfa-triples/0072.nt +1 -0
  105. data/spec/rdfa-triples/0073.nt +1 -0
  106. data/spec/rdfa-triples/0074.nt +1 -0
  107. data/spec/rdfa-triples/0075.nt +1 -0
  108. data/spec/rdfa-triples/0076.nt +23 -0
  109. data/spec/rdfa-triples/0077.nt +23 -0
  110. data/spec/rdfa-triples/0078.nt +6 -0
  111. data/spec/rdfa-triples/0079.nt +3 -0
  112. data/spec/rdfa-triples/0080.nt +1 -0
  113. data/spec/rdfa-triples/0081.nt +6 -0
  114. data/spec/rdfa-triples/0082.nt +8 -0
  115. data/spec/rdfa-triples/0083.nt +6 -0
  116. data/spec/rdfa-triples/0084.nt +8 -0
  117. data/spec/rdfa-triples/0085.nt +4 -0
  118. data/spec/rdfa-triples/0086.nt +0 -0
  119. data/spec/rdfa-triples/0087.nt +23 -0
  120. data/spec/rdfa-triples/0088.nt +3 -0
  121. data/spec/rdfa-triples/0089.nt +1 -0
  122. data/spec/rdfa-triples/0090.nt +1 -0
  123. data/spec/rdfa-triples/0091.nt +3 -0
  124. data/spec/rdfa-triples/0092.nt +3 -0
  125. data/spec/rdfa-triples/0093.nt +2 -0
  126. data/spec/rdfa-triples/0094.nt +3 -0
  127. data/spec/rdfa-triples/0099.nt +1 -0
  128. data/spec/rdfa-triples/0100.nt +3 -0
  129. data/spec/rdfa-triples/0101.nt +3 -0
  130. data/spec/rdfa-triples/0102.nt +1 -0
  131. data/spec/rdfa-triples/0103.nt +1 -0
  132. data/spec/rdfa-triples/0104.nt +3 -0
  133. data/spec/rdfa-triples/0105.nt +1 -0
  134. data/spec/rdfa-triples/0106.nt +1 -0
  135. data/spec/rdfa-triples/0107.nt +0 -0
  136. data/spec/rdfa-triples/0108.nt +1 -0
  137. data/spec/rdfa-triples/0109.nt +1 -0
  138. data/spec/rdfa-triples/0110.nt +1 -0
  139. data/spec/rdfa-triples/0111.nt +2 -0
  140. data/spec/rdfa-triples/0112.nt +1 -0
  141. data/spec/rdfa-triples/0113.nt +2 -0
  142. data/spec/rdfa-triples/0114.nt +3 -0
  143. data/spec/rdfa-triples/0115.nt +4 -0
  144. data/spec/rdfa-triples/0116.nt +2 -0
  145. data/spec/rdfa-triples/0117.nt +2 -0
  146. data/spec/rdfa-triples/0118.nt +1 -0
  147. data/spec/rdfa-triples/0119.nt +1 -0
  148. data/spec/rdfa-triples/0120.nt +1 -0
  149. data/spec/rdfa-triples/0121.nt +2 -0
  150. data/spec/rdfa-triples/0122.nt +1 -0
  151. data/spec/rdfa-triples/0123.nt +3 -0
  152. data/spec/rdfa-triples/0124.nt +4 -0
  153. data/spec/rdfa-triples/0125.nt +1 -0
  154. data/spec/rdfa-triples/0126.nt +3 -0
  155. data/spec/rdfa-triples/1001.nt +6 -0
  156. data/spec/rdfa_helper.rb +189 -0
  157. data/spec/rdfa_parser_spec.rb +148 -0
  158. data/spec/rdfcore/Manifest.rdf +5395 -0
  159. data/spec/rdfcore/amp-in-url/test001.nt +16 -0
  160. data/spec/rdfcore/amp-in-url/test001.rdf +40 -0
  161. data/spec/rdfcore/datatypes-intensional/test001.nt +18 -0
  162. data/spec/rdfcore/datatypes-intensional/test002.nt +18 -0
  163. data/spec/rdfcore/datatypes/test001.nt +15 -0
  164. data/spec/rdfcore/datatypes/test001.rdf +29 -0
  165. data/spec/rdfcore/datatypes/test002.nt +14 -0
  166. data/spec/rdfcore/datatypes/test002.rdf +27 -0
  167. data/spec/rdfcore/datatypes/test002b.nt +17 -0
  168. data/spec/rdfcore/datatypes/test003a.nt +16 -0
  169. data/spec/rdfcore/datatypes/test003b.nt +16 -0
  170. data/spec/rdfcore/datatypes/test005a.nt +16 -0
  171. data/spec/rdfcore/datatypes/test005b.nt +16 -0
  172. data/spec/rdfcore/datatypes/test006.nt +17 -0
  173. data/spec/rdfcore/datatypes/test008a.nt +15 -0
  174. data/spec/rdfcore/datatypes/test008b.nt +15 -0
  175. data/spec/rdfcore/datatypes/test009a.nt +15 -0
  176. data/spec/rdfcore/datatypes/test009b.nt +15 -0
  177. data/spec/rdfcore/datatypes/test010.nt +17 -0
  178. data/spec/rdfcore/datatypes/test011a.nt +17 -0
  179. data/spec/rdfcore/datatypes/test011b.nt +17 -0
  180. data/spec/rdfcore/horst-01/test001.rdf +38 -0
  181. data/spec/rdfcore/horst-01/test002.rdf +39 -0
  182. data/spec/rdfcore/horst-01/test003.rdf +40 -0
  183. data/spec/rdfcore/horst-01/test004.rdf +42 -0
  184. data/spec/rdfcore/pfps-10/test001a.nt +14 -0
  185. data/spec/rdfcore/pfps-10/test001b.nt +15 -0
  186. data/spec/rdfcore/rdf-charmod-literals/test001.nt +15 -0
  187. data/spec/rdfcore/rdf-charmod-literals/test001.rdf +34 -0
  188. data/spec/rdfcore/rdf-charmod-uris/test001.nt +14 -0
  189. data/spec/rdfcore/rdf-charmod-uris/test001.rdf +34 -0
  190. data/spec/rdfcore/rdf-charmod-uris/test002.nt +15 -0
  191. data/spec/rdfcore/rdf-charmod-uris/test002.rdf +33 -0
  192. data/spec/rdfcore/rdf-containers-syntax-vs-schema/error001.rdf +27 -0
  193. data/spec/rdfcore/rdf-containers-syntax-vs-schema/error002.rdf +34 -0
  194. data/spec/rdfcore/rdf-containers-syntax-vs-schema/test001.nt +17 -0
  195. data/spec/rdfcore/rdf-containers-syntax-vs-schema/test001.rdf +27 -0
  196. data/spec/rdfcore/rdf-containers-syntax-vs-schema/test002.nt +19 -0
  197. data/spec/rdfcore/rdf-containers-syntax-vs-schema/test002.rdf +37 -0
  198. data/spec/rdfcore/rdf-containers-syntax-vs-schema/test003.nt +18 -0
  199. data/spec/rdfcore/rdf-containers-syntax-vs-schema/test003.rdf +29 -0
  200. data/spec/rdfcore/rdf-containers-syntax-vs-schema/test004.nt +29 -0
  201. data/spec/rdfcore/rdf-containers-syntax-vs-schema/test004.rdf +33 -0
  202. data/spec/rdfcore/rdf-containers-syntax-vs-schema/test006.nt +40 -0
  203. data/spec/rdfcore/rdf-containers-syntax-vs-schema/test006.rdf +28 -0
  204. data/spec/rdfcore/rdf-containers-syntax-vs-schema/test007.nt +20 -0
  205. data/spec/rdfcore/rdf-containers-syntax-vs-schema/test007.rdf +32 -0
  206. data/spec/rdfcore/rdf-containers-syntax-vs-schema/test008.nt +15 -0
  207. data/spec/rdfcore/rdf-containers-syntax-vs-schema/test008.rdf +28 -0
  208. data/spec/rdfcore/rdf-element-not-mandatory/test001.nt +10 -0
  209. data/spec/rdfcore/rdf-element-not-mandatory/test001.rdf +14 -0
  210. data/spec/rdfcore/rdf-ns-prefix-confusion/test0001.nt +14 -0
  211. data/spec/rdfcore/rdf-ns-prefix-confusion/test0001.rdf +35 -0
  212. data/spec/rdfcore/rdf-ns-prefix-confusion/test0003.nt +14 -0
  213. data/spec/rdfcore/rdf-ns-prefix-confusion/test0003.rdf +35 -0
  214. data/spec/rdfcore/rdf-ns-prefix-confusion/test0004.nt +14 -0
  215. data/spec/rdfcore/rdf-ns-prefix-confusion/test0004.rdf +34 -0
  216. data/spec/rdfcore/rdf-ns-prefix-confusion/test0005.nt +15 -0
  217. data/spec/rdfcore/rdf-ns-prefix-confusion/test0005.rdf +40 -0
  218. data/spec/rdfcore/rdf-ns-prefix-confusion/test0006.nt +14 -0
  219. data/spec/rdfcore/rdf-ns-prefix-confusion/test0006.rdf +32 -0
  220. data/spec/rdfcore/rdf-ns-prefix-confusion/test0009.nt +14 -0
  221. data/spec/rdfcore/rdf-ns-prefix-confusion/test0009.rdf +32 -0
  222. data/spec/rdfcore/rdf-ns-prefix-confusion/test0010.nt +14 -0
  223. data/spec/rdfcore/rdf-ns-prefix-confusion/test0010.rdf +38 -0
  224. data/spec/rdfcore/rdf-ns-prefix-confusion/test0011.nt +15 -0
  225. data/spec/rdfcore/rdf-ns-prefix-confusion/test0011.rdf +40 -0
  226. data/spec/rdfcore/rdf-ns-prefix-confusion/test0012.nt +15 -0
  227. data/spec/rdfcore/rdf-ns-prefix-confusion/test0012.rdf +40 -0
  228. data/spec/rdfcore/rdf-ns-prefix-confusion/test0013.nt +15 -0
  229. data/spec/rdfcore/rdf-ns-prefix-confusion/test0013.rdf +40 -0
  230. data/spec/rdfcore/rdf-ns-prefix-confusion/test0014.nt +15 -0
  231. data/spec/rdfcore/rdf-ns-prefix-confusion/test0014.rdf +42 -0
  232. data/spec/rdfcore/rdfms-abouteach/error001.rdf +35 -0
  233. data/spec/rdfcore/rdfms-abouteach/error002.rdf +35 -0
  234. data/spec/rdfcore/rdfms-difference-between-ID-and-about/error1.rdf +25 -0
  235. data/spec/rdfcore/rdfms-difference-between-ID-and-about/test1.nt +14 -0
  236. data/spec/rdfcore/rdfms-difference-between-ID-and-about/test1.rdf +22 -0
  237. data/spec/rdfcore/rdfms-difference-between-ID-and-about/test2.nt +14 -0
  238. data/spec/rdfcore/rdfms-difference-between-ID-and-about/test2.rdf +22 -0
  239. data/spec/rdfcore/rdfms-difference-between-ID-and-about/test3.nt +14 -0
  240. data/spec/rdfcore/rdfms-difference-between-ID-and-about/test3.rdf +22 -0
  241. data/spec/rdfcore/rdfms-duplicate-member-props/test001.nt +17 -0
  242. data/spec/rdfcore/rdfms-duplicate-member-props/test001.rdf +30 -0
  243. data/spec/rdfcore/rdfms-empty-property-elements/error001.rdf +33 -0
  244. data/spec/rdfcore/rdfms-empty-property-elements/error002.rdf +33 -0
  245. data/spec/rdfcore/rdfms-empty-property-elements/error003.rdf +39 -0
  246. data/spec/rdfcore/rdfms-empty-property-elements/test001.nt +14 -0
  247. data/spec/rdfcore/rdfms-empty-property-elements/test001.rdf +33 -0
  248. data/spec/rdfcore/rdfms-empty-property-elements/test002.nt +14 -0
  249. data/spec/rdfcore/rdfms-empty-property-elements/test002.rdf +31 -0
  250. data/spec/rdfcore/rdfms-empty-property-elements/test003.nt +14 -0
  251. data/spec/rdfcore/rdfms-empty-property-elements/test003.rdf +32 -0
  252. data/spec/rdfcore/rdfms-empty-property-elements/test004.nt +14 -0
  253. data/spec/rdfcore/rdfms-empty-property-elements/test004.rdf +32 -0
  254. data/spec/rdfcore/rdfms-empty-property-elements/test005.nt +18 -0
  255. data/spec/rdfcore/rdfms-empty-property-elements/test005.rdf +32 -0
  256. data/spec/rdfcore/rdfms-empty-property-elements/test006.nt +18 -0
  257. data/spec/rdfcore/rdfms-empty-property-elements/test006.rdf +32 -0
  258. data/spec/rdfcore/rdfms-empty-property-elements/test007.nt +14 -0
  259. data/spec/rdfcore/rdfms-empty-property-elements/test007.rdf +32 -0
  260. data/spec/rdfcore/rdfms-empty-property-elements/test008.nt +14 -0
  261. data/spec/rdfcore/rdfms-empty-property-elements/test008.rdf +31 -0
  262. data/spec/rdfcore/rdfms-empty-property-elements/test009.nt +14 -0
  263. data/spec/rdfcore/rdfms-empty-property-elements/test009.rdf +32 -0
  264. data/spec/rdfcore/rdfms-empty-property-elements/test010.nt +14 -0
  265. data/spec/rdfcore/rdfms-empty-property-elements/test010.rdf +31 -0
  266. data/spec/rdfcore/rdfms-empty-property-elements/test011.nt +18 -0
  267. data/spec/rdfcore/rdfms-empty-property-elements/test011.rdf +30 -0
  268. data/spec/rdfcore/rdfms-empty-property-elements/test012.nt +18 -0
  269. data/spec/rdfcore/rdfms-empty-property-elements/test012.rdf +30 -0
  270. data/spec/rdfcore/rdfms-empty-property-elements/test013.nt +15 -0
  271. data/spec/rdfcore/rdfms-empty-property-elements/test013.rdf +35 -0
  272. data/spec/rdfcore/rdfms-empty-property-elements/test014.nt +15 -0
  273. data/spec/rdfcore/rdfms-empty-property-elements/test014.rdf +34 -0
  274. data/spec/rdfcore/rdfms-empty-property-elements/test015.nt +15 -0
  275. data/spec/rdfcore/rdfms-empty-property-elements/test015.rdf +38 -0
  276. data/spec/rdfcore/rdfms-empty-property-elements/test016.nt +14 -0
  277. data/spec/rdfcore/rdfms-empty-property-elements/test016.rdf +31 -0
  278. data/spec/rdfcore/rdfms-empty-property-elements/test017.nt +14 -0
  279. data/spec/rdfcore/rdfms-empty-property-elements/test017.rdf +38 -0
  280. data/spec/rdfcore/rdfms-identity-anon-resources/test001.nt +14 -0
  281. data/spec/rdfcore/rdfms-identity-anon-resources/test001.rdf +33 -0
  282. data/spec/rdfcore/rdfms-identity-anon-resources/test002.nt +15 -0
  283. data/spec/rdfcore/rdfms-identity-anon-resources/test002.rdf +33 -0
  284. data/spec/rdfcore/rdfms-identity-anon-resources/test003.nt +14 -0
  285. data/spec/rdfcore/rdfms-identity-anon-resources/test003.rdf +31 -0
  286. data/spec/rdfcore/rdfms-identity-anon-resources/test004.nt +15 -0
  287. data/spec/rdfcore/rdfms-identity-anon-resources/test004.rdf +33 -0
  288. data/spec/rdfcore/rdfms-identity-anon-resources/test005.nt +14 -0
  289. data/spec/rdfcore/rdfms-identity-anon-resources/test005.rdf +31 -0
  290. data/spec/rdfcore/rdfms-not-id-and-resource-attr/test001.nt +19 -0
  291. data/spec/rdfcore/rdfms-not-id-and-resource-attr/test001.rdf +29 -0
  292. data/spec/rdfcore/rdfms-not-id-and-resource-attr/test002.nt +15 -0
  293. data/spec/rdfcore/rdfms-not-id-and-resource-attr/test002.rdf +29 -0
  294. data/spec/rdfcore/rdfms-not-id-and-resource-attr/test004.nt +18 -0
  295. data/spec/rdfcore/rdfms-not-id-and-resource-attr/test004.rdf +29 -0
  296. data/spec/rdfcore/rdfms-not-id-and-resource-attr/test005.nt +19 -0
  297. data/spec/rdfcore/rdfms-not-id-and-resource-attr/test005.rdf +29 -0
  298. data/spec/rdfcore/rdfms-para196/test001.nt +17 -0
  299. data/spec/rdfcore/rdfms-para196/test001.rdf +35 -0
  300. data/spec/rdfcore/rdfms-rdf-id/error001.rdf +26 -0
  301. data/spec/rdfcore/rdfms-rdf-id/error002.rdf +26 -0
  302. data/spec/rdfcore/rdfms-rdf-id/error003.rdf +29 -0
  303. data/spec/rdfcore/rdfms-rdf-id/error004.rdf +27 -0
  304. data/spec/rdfcore/rdfms-rdf-id/error005.rdf +31 -0
  305. data/spec/rdfcore/rdfms-rdf-id/error006.rdf +26 -0
  306. data/spec/rdfcore/rdfms-rdf-id/error007.rdf +29 -0
  307. data/spec/rdfcore/rdfms-rdf-names-use/error-001.rdf +23 -0
  308. data/spec/rdfcore/rdfms-rdf-names-use/error-002.rdf +23 -0
  309. data/spec/rdfcore/rdfms-rdf-names-use/error-003.rdf +23 -0
  310. data/spec/rdfcore/rdfms-rdf-names-use/error-004.rdf +23 -0
  311. data/spec/rdfcore/rdfms-rdf-names-use/error-005.rdf +23 -0
  312. data/spec/rdfcore/rdfms-rdf-names-use/error-006.rdf +23 -0
  313. data/spec/rdfcore/rdfms-rdf-names-use/error-007.rdf +23 -0
  314. data/spec/rdfcore/rdfms-rdf-names-use/error-008.rdf +23 -0
  315. data/spec/rdfcore/rdfms-rdf-names-use/error-009.rdf +23 -0
  316. data/spec/rdfcore/rdfms-rdf-names-use/error-010.rdf +23 -0
  317. data/spec/rdfcore/rdfms-rdf-names-use/error-011.rdf +25 -0
  318. data/spec/rdfcore/rdfms-rdf-names-use/error-012.rdf +25 -0
  319. data/spec/rdfcore/rdfms-rdf-names-use/error-013.rdf +25 -0
  320. data/spec/rdfcore/rdfms-rdf-names-use/error-014.rdf +25 -0
  321. data/spec/rdfcore/rdfms-rdf-names-use/error-015.rdf +25 -0
  322. data/spec/rdfcore/rdfms-rdf-names-use/error-016.rdf +25 -0
  323. data/spec/rdfcore/rdfms-rdf-names-use/error-017.rdf +25 -0
  324. data/spec/rdfcore/rdfms-rdf-names-use/error-018.rdf +25 -0
  325. data/spec/rdfcore/rdfms-rdf-names-use/error-019.rdf +25 -0
  326. data/spec/rdfcore/rdfms-rdf-names-use/error-020.rdf +25 -0
  327. data/spec/rdfcore/rdfms-rdf-names-use/test-001.nt +1 -0
  328. data/spec/rdfcore/rdfms-rdf-names-use/test-001.rdf +23 -0
  329. data/spec/rdfcore/rdfms-rdf-names-use/test-002.nt +1 -0
  330. data/spec/rdfcore/rdfms-rdf-names-use/test-002.rdf +23 -0
  331. data/spec/rdfcore/rdfms-rdf-names-use/test-003.nt +1 -0
  332. data/spec/rdfcore/rdfms-rdf-names-use/test-003.rdf +23 -0
  333. data/spec/rdfcore/rdfms-rdf-names-use/test-004.nt +1 -0
  334. data/spec/rdfcore/rdfms-rdf-names-use/test-004.rdf +23 -0
  335. data/spec/rdfcore/rdfms-rdf-names-use/test-005.nt +1 -0
  336. data/spec/rdfcore/rdfms-rdf-names-use/test-005.rdf +23 -0
  337. data/spec/rdfcore/rdfms-rdf-names-use/test-006.nt +1 -0
  338. data/spec/rdfcore/rdfms-rdf-names-use/test-006.rdf +23 -0
  339. data/spec/rdfcore/rdfms-rdf-names-use/test-007.nt +1 -0
  340. data/spec/rdfcore/rdfms-rdf-names-use/test-007.rdf +23 -0
  341. data/spec/rdfcore/rdfms-rdf-names-use/test-008.nt +1 -0
  342. data/spec/rdfcore/rdfms-rdf-names-use/test-008.rdf +23 -0
  343. data/spec/rdfcore/rdfms-rdf-names-use/test-009.nt +1 -0
  344. data/spec/rdfcore/rdfms-rdf-names-use/test-009.rdf +23 -0
  345. data/spec/rdfcore/rdfms-rdf-names-use/test-010.nt +1 -0
  346. data/spec/rdfcore/rdfms-rdf-names-use/test-010.rdf +23 -0
  347. data/spec/rdfcore/rdfms-rdf-names-use/test-011.nt +1 -0
  348. data/spec/rdfcore/rdfms-rdf-names-use/test-011.rdf +23 -0
  349. data/spec/rdfcore/rdfms-rdf-names-use/test-012.nt +1 -0
  350. data/spec/rdfcore/rdfms-rdf-names-use/test-012.rdf +23 -0
  351. data/spec/rdfcore/rdfms-rdf-names-use/test-013.nt +1 -0
  352. data/spec/rdfcore/rdfms-rdf-names-use/test-013.rdf +23 -0
  353. data/spec/rdfcore/rdfms-rdf-names-use/test-014.nt +1 -0
  354. data/spec/rdfcore/rdfms-rdf-names-use/test-014.rdf +23 -0
  355. data/spec/rdfcore/rdfms-rdf-names-use/test-015.nt +1 -0
  356. data/spec/rdfcore/rdfms-rdf-names-use/test-015.rdf +23 -0
  357. data/spec/rdfcore/rdfms-rdf-names-use/test-016.nt +1 -0
  358. data/spec/rdfcore/rdfms-rdf-names-use/test-016.rdf +23 -0
  359. data/spec/rdfcore/rdfms-rdf-names-use/test-017.nt +1 -0
  360. data/spec/rdfcore/rdfms-rdf-names-use/test-017.rdf +25 -0
  361. data/spec/rdfcore/rdfms-rdf-names-use/test-018.nt +1 -0
  362. data/spec/rdfcore/rdfms-rdf-names-use/test-018.rdf +25 -0
  363. data/spec/rdfcore/rdfms-rdf-names-use/test-019.nt +1 -0
  364. data/spec/rdfcore/rdfms-rdf-names-use/test-019.rdf +25 -0
  365. data/spec/rdfcore/rdfms-rdf-names-use/test-020.nt +1 -0
  366. data/spec/rdfcore/rdfms-rdf-names-use/test-020.rdf +25 -0
  367. data/spec/rdfcore/rdfms-rdf-names-use/test-021.nt +1 -0
  368. data/spec/rdfcore/rdfms-rdf-names-use/test-021.rdf +25 -0
  369. data/spec/rdfcore/rdfms-rdf-names-use/test-022.nt +1 -0
  370. data/spec/rdfcore/rdfms-rdf-names-use/test-022.rdf +25 -0
  371. data/spec/rdfcore/rdfms-rdf-names-use/test-023.nt +1 -0
  372. data/spec/rdfcore/rdfms-rdf-names-use/test-023.rdf +25 -0
  373. data/spec/rdfcore/rdfms-rdf-names-use/test-024.nt +1 -0
  374. data/spec/rdfcore/rdfms-rdf-names-use/test-024.rdf +25 -0
  375. data/spec/rdfcore/rdfms-rdf-names-use/test-025.nt +1 -0
  376. data/spec/rdfcore/rdfms-rdf-names-use/test-025.rdf +25 -0
  377. data/spec/rdfcore/rdfms-rdf-names-use/test-026.nt +1 -0
  378. data/spec/rdfcore/rdfms-rdf-names-use/test-026.rdf +25 -0
  379. data/spec/rdfcore/rdfms-rdf-names-use/test-027.nt +1 -0
  380. data/spec/rdfcore/rdfms-rdf-names-use/test-027.rdf +25 -0
  381. data/spec/rdfcore/rdfms-rdf-names-use/test-028.nt +1 -0
  382. data/spec/rdfcore/rdfms-rdf-names-use/test-028.rdf +25 -0
  383. data/spec/rdfcore/rdfms-rdf-names-use/test-029.nt +1 -0
  384. data/spec/rdfcore/rdfms-rdf-names-use/test-029.rdf +25 -0
  385. data/spec/rdfcore/rdfms-rdf-names-use/test-030.nt +1 -0
  386. data/spec/rdfcore/rdfms-rdf-names-use/test-030.rdf +25 -0
  387. data/spec/rdfcore/rdfms-rdf-names-use/test-031.nt +1 -0
  388. data/spec/rdfcore/rdfms-rdf-names-use/test-031.rdf +25 -0
  389. data/spec/rdfcore/rdfms-rdf-names-use/test-032.nt +1 -0
  390. data/spec/rdfcore/rdfms-rdf-names-use/test-032.rdf +24 -0
  391. data/spec/rdfcore/rdfms-rdf-names-use/test-033.nt +1 -0
  392. data/spec/rdfcore/rdfms-rdf-names-use/test-033.rdf +24 -0
  393. data/spec/rdfcore/rdfms-rdf-names-use/test-034.nt +1 -0
  394. data/spec/rdfcore/rdfms-rdf-names-use/test-034.rdf +24 -0
  395. data/spec/rdfcore/rdfms-rdf-names-use/test-035.nt +1 -0
  396. data/spec/rdfcore/rdfms-rdf-names-use/test-035.rdf +24 -0
  397. data/spec/rdfcore/rdfms-rdf-names-use/test-036.nt +1 -0
  398. data/spec/rdfcore/rdfms-rdf-names-use/test-036.rdf +24 -0
  399. data/spec/rdfcore/rdfms-rdf-names-use/test-037.nt +1 -0
  400. data/spec/rdfcore/rdfms-rdf-names-use/test-037.rdf +24 -0
  401. data/spec/rdfcore/rdfms-rdf-names-use/warn-001.nt +1 -0
  402. data/spec/rdfcore/rdfms-rdf-names-use/warn-001.rdf +23 -0
  403. data/spec/rdfcore/rdfms-rdf-names-use/warn-002.nt +1 -0
  404. data/spec/rdfcore/rdfms-rdf-names-use/warn-002.rdf +25 -0
  405. data/spec/rdfcore/rdfms-rdf-names-use/warn-003.nt +1 -0
  406. data/spec/rdfcore/rdfms-rdf-names-use/warn-003.rdf +24 -0
  407. data/spec/rdfcore/rdfms-reification-required/test001.nt +15 -0
  408. data/spec/rdfcore/rdfms-reification-required/test001.rdf +29 -0
  409. data/spec/rdfcore/rdfms-seq-representation/empty.nt +13 -0
  410. data/spec/rdfcore/rdfms-seq-representation/test001.nt +19 -0
  411. data/spec/rdfcore/rdfms-seq-representation/test001.rdf +33 -0
  412. data/spec/rdfcore/rdfms-seq-representation/test002.nt +14 -0
  413. data/spec/rdfcore/rdfms-seq-representation/test003a.nt +14 -0
  414. data/spec/rdfcore/rdfms-seq-representation/test003b.nt +14 -0
  415. data/spec/rdfcore/rdfms-seq-representation/test004.nt +14 -0
  416. data/spec/rdfcore/rdfms-syntax-incomplete/error001.rdf +26 -0
  417. data/spec/rdfcore/rdfms-syntax-incomplete/error002.rdf +26 -0
  418. data/spec/rdfcore/rdfms-syntax-incomplete/error003.rdf +29 -0
  419. data/spec/rdfcore/rdfms-syntax-incomplete/error004.rdf +25 -0
  420. data/spec/rdfcore/rdfms-syntax-incomplete/error005.rdf +25 -0
  421. data/spec/rdfcore/rdfms-syntax-incomplete/error006.rdf +28 -0
  422. data/spec/rdfcore/rdfms-syntax-incomplete/test001.nt +14 -0
  423. data/spec/rdfcore/rdfms-syntax-incomplete/test001.rdf +28 -0
  424. data/spec/rdfcore/rdfms-syntax-incomplete/test002.nt +19 -0
  425. data/spec/rdfcore/rdfms-syntax-incomplete/test002.rdf +38 -0
  426. data/spec/rdfcore/rdfms-syntax-incomplete/test003.nt +17 -0
  427. data/spec/rdfcore/rdfms-syntax-incomplete/test003.rdf +28 -0
  428. data/spec/rdfcore/rdfms-syntax-incomplete/test004.nt +21 -0
  429. data/spec/rdfcore/rdfms-syntax-incomplete/test004.rdf +36 -0
  430. data/spec/rdfcore/rdfms-uri-substructure/error001.nt +18 -0
  431. data/spec/rdfcore/rdfms-uri-substructure/test001.nt +17 -0
  432. data/spec/rdfcore/rdfms-uri-substructure/test001.rdf +29 -0
  433. data/spec/rdfcore/rdfms-xml-literal-namespaces/test001.nt +13 -0
  434. data/spec/rdfcore/rdfms-xml-literal-namespaces/test001.rdf +33 -0
  435. data/spec/rdfcore/rdfms-xml-literal-namespaces/test002.nt +14 -0
  436. data/spec/rdfcore/rdfms-xml-literal-namespaces/test002.rdf +47 -0
  437. data/spec/rdfcore/rdfms-xmllang/test001.nt +14 -0
  438. data/spec/rdfcore/rdfms-xmllang/test001.rdf +30 -0
  439. data/spec/rdfcore/rdfms-xmllang/test002.nt +14 -0
  440. data/spec/rdfcore/rdfms-xmllang/test002.rdf +29 -0
  441. data/spec/rdfcore/rdfms-xmllang/test003.nt +14 -0
  442. data/spec/rdfcore/rdfms-xmllang/test003.rdf +28 -0
  443. data/spec/rdfcore/rdfms-xmllang/test004.nt +14 -0
  444. data/spec/rdfcore/rdfms-xmllang/test004.rdf +28 -0
  445. data/spec/rdfcore/rdfms-xmllang/test005.nt +14 -0
  446. data/spec/rdfcore/rdfms-xmllang/test005.rdf +28 -0
  447. data/spec/rdfcore/rdfms-xmllang/test006.nt +14 -0
  448. data/spec/rdfcore/rdfms-xmllang/test006.rdf +29 -0
  449. data/spec/rdfcore/rdfms-xmllang/test007a.nt +14 -0
  450. data/spec/rdfcore/rdfms-xmllang/test007b.nt +14 -0
  451. data/spec/rdfcore/rdfms-xmllang/test007c.nt +14 -0
  452. data/spec/rdfcore/rdfs-container-membership-superProperty/not1C.rdf +13 -0
  453. data/spec/rdfcore/rdfs-container-membership-superProperty/not1P.rdf +14 -0
  454. data/spec/rdfcore/rdfs-domain-and-range/nonconclusions005.rdf +28 -0
  455. data/spec/rdfcore/rdfs-domain-and-range/nonconclusions006.rdf +28 -0
  456. data/spec/rdfcore/rdfs-domain-and-range/premises005.rdf +32 -0
  457. data/spec/rdfcore/rdfs-domain-and-range/premises006.rdf +32 -0
  458. data/spec/rdfcore/rdfs-domain-and-range/test001.nt +16 -0
  459. data/spec/rdfcore/rdfs-domain-and-range/test001.rdf +29 -0
  460. data/spec/rdfcore/rdfs-domain-and-range/test002.nt +16 -0
  461. data/spec/rdfcore/rdfs-domain-and-range/test002.rdf +29 -0
  462. data/spec/rdfcore/rdfs-entailment/test001.nt +16 -0
  463. data/spec/rdfcore/rdfs-entailment/test002.nt +15 -0
  464. data/spec/rdfcore/rdfs-no-cycles-in-subClassOf/test001.nt +18 -0
  465. data/spec/rdfcore/rdfs-no-cycles-in-subClassOf/test001.rdf +37 -0
  466. data/spec/rdfcore/rdfs-no-cycles-in-subPropertyOf/test001.nt +18 -0
  467. data/spec/rdfcore/rdfs-no-cycles-in-subPropertyOf/test001.rdf +40 -0
  468. data/spec/rdfcore/rdfs-subClassOf-a-Property/test001.nt +15 -0
  469. data/spec/rdfcore/rdfs-subPropertyOf-semantics/test001.nt +24 -0
  470. data/spec/rdfcore/rdfs-subPropertyOf-semantics/test002.nt +21 -0
  471. data/spec/rdfcore/statement-entailment/test001a.nt +12 -0
  472. data/spec/rdfcore/statement-entailment/test001b.nt +2 -0
  473. data/spec/rdfcore/statement-entailment/test002a.nt +2 -0
  474. data/spec/rdfcore/statement-entailment/test002b.nt +5 -0
  475. data/spec/rdfcore/tex-01/test001.rdf +34 -0
  476. data/spec/rdfcore/tex-01/test002.rdf +33 -0
  477. data/spec/rdfcore/unrecognised-xml-attributes/test001.nt +15 -0
  478. data/spec/rdfcore/unrecognised-xml-attributes/test001.rdf +31 -0
  479. data/spec/rdfcore/unrecognised-xml-attributes/test002.nt +14 -0
  480. data/spec/rdfcore/unrecognised-xml-attributes/test002.rdf +32 -0
  481. data/spec/rdfcore/xml-canon/test001.nt +16 -0
  482. data/spec/rdfcore/xml-canon/test001.rdf +28 -0
  483. data/spec/rdfcore/xmlbase/test001.nt +14 -0
  484. data/spec/rdfcore/xmlbase/test001.rdf +27 -0
  485. data/spec/rdfcore/xmlbase/test002.nt +14 -0
  486. data/spec/rdfcore/xmlbase/test002.rdf +28 -0
  487. data/spec/rdfcore/xmlbase/test003.nt +14 -0
  488. data/spec/rdfcore/xmlbase/test003.rdf +25 -0
  489. data/spec/rdfcore/xmlbase/test004.nt +18 -0
  490. data/spec/rdfcore/xmlbase/test004.rdf +27 -0
  491. data/spec/rdfcore/xmlbase/test006.nt +15 -0
  492. data/spec/rdfcore/xmlbase/test006.rdf +26 -0
  493. data/spec/rdfcore/xmlbase/test007.nt +14 -0
  494. data/spec/rdfcore/xmlbase/test007.rdf +25 -0
  495. data/spec/rdfcore/xmlbase/test008.nt +14 -0
  496. data/spec/rdfcore/xmlbase/test008.rdf +25 -0
  497. data/spec/rdfcore/xmlbase/test009.nt +14 -0
  498. data/spec/rdfcore/xmlbase/test009.rdf +26 -0
  499. data/spec/rdfcore/xmlbase/test010.nt +14 -0
  500. data/spec/rdfcore/xmlbase/test010.rdf +26 -0
  501. data/spec/rdfcore/xmlbase/test011.nt +14 -0
  502. data/spec/rdfcore/xmlbase/test011.rdf +27 -0
  503. data/spec/rdfcore/xmlbase/test013.nt +15 -0
  504. data/spec/rdfcore/xmlbase/test013.rdf +28 -0
  505. data/spec/rdfcore/xmlbase/test014.nt +15 -0
  506. data/spec/rdfcore/xmlbase/test014.rdf +28 -0
  507. data/spec/rdfcore/xmlsch-02/test001.rdf +34 -0
  508. data/spec/rdfcore/xmlsch-02/test002.rdf +34 -0
  509. data/spec/rdfcore/xmlsch-02/test003.rdf +37 -0
  510. data/spec/rdfxml_helper.rb +137 -0
  511. data/spec/rdfxml_spec.rb +362 -0
  512. data/spec/spec.opts +1 -0
  513. data/spec/spec_helper.rb +23 -0
  514. data/spec/sqlite3_store_spec.rb +41 -0
  515. data/spec/store_helper.rb +231 -0
  516. data/spec/string_hacks_spec.rb +21 -0
  517. data/spec/triple_spec.rb +172 -0
  518. data/spec/uriref_spec.rb +117 -0
  519. data/test/longtests_spec.rb +25 -0
  520. data/test/n3_tests/lcsh/sh85062913.n3 +41 -0
  521. data/test/n3_tests/lcsh/sh85062913.nt +21 -0
  522. data/test/n3_tests/lcsh/sh85082139.n3 +157 -0
  523. data/test/n3_tests/lcsh/sh85082139.nt +79 -0
  524. data/test/n3_tests/lcsh/sh85118553.n3 +123 -0
  525. data/test/n3_tests/lcsh/sh85118553.nt +63 -0
  526. data/test/n3_tests/misc/on_now-01.n3 +30 -0
  527. data/test/n3_tests/misc/on_now-01.nt +15 -0
  528. data/test/n3_tests/n3p/simple-01.n3 +1 -0
  529. data/test/n3_tests/n3p/simple-01.nt +0 -0
  530. data/test/n3_tests/n3p/simple-02.n3 +4 -0
  531. data/test/n3_tests/n3p/simple-02.nt +0 -0
  532. data/test/n3_tests/n3p/simple-03.n3 +5 -0
  533. data/test/n3_tests/n3p/simple-03.nt +1 -0
  534. data/test/n3_tests/n3p/simple-04.n3 +6 -0
  535. data/test/n3_tests/n3p/simple-04.nt +3 -0
  536. data/test/n3_tests/n3p/simple-05.n3 +7 -0
  537. data/test/n3_tests/n3p/simple-05.nt +2 -0
  538. data/test/n3_tests/n3p/simple-06.n3 +6 -0
  539. data/test/n3_tests/n3p/simple-06.nt +4 -0
  540. data/test/n3_tests/n3p/simple-07.n3 +7 -0
  541. data/test/n3_tests/n3p/simple-07.nt +6 -0
  542. data/test/perf_test/test.rb +11 -0
  543. data/test/perf_test/tommorris.rdf +2267 -0
  544. data/test/rdf_tests/cc197bad-dc9c-440d-a5b5-d52ba2e14234.nt +24 -0
  545. data/test/rdf_tests/cc197bad-dc9c-440d-a5b5-d52ba2e14234.rdf +46 -0
  546. data/test/rdf_tests/tm_001.nt +1 -0
  547. data/test/rdf_tests/tm_001.rdf +7 -0
  548. data/test/rdf_tests/xml-literal-mixed.nt +7 -0
  549. data/test/rdf_tests/xml-literal-mixed.rdf +15 -0
  550. data/test/xml.rdf +6 -0
  551. 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
OSZAR »