rdf_context 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
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