gkellogg-reddy 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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