gkellogg-reddy 0.2.1

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