danielebarchiesi@4
|
1 <?php
|
danielebarchiesi@4
|
2 /**
|
danielebarchiesi@4
|
3 * ARC2 RDF/XML Serializer
|
danielebarchiesi@4
|
4 *
|
danielebarchiesi@4
|
5 * @author Benjamin Nowack
|
danielebarchiesi@4
|
6 * @license <http://arc.semsol.org/license>
|
danielebarchiesi@4
|
7 * @homepage <http://arc.semsol.org/>
|
danielebarchiesi@4
|
8 * @package ARC2
|
danielebarchiesi@4
|
9 * @version 2010-11-16
|
danielebarchiesi@4
|
10 */
|
danielebarchiesi@4
|
11
|
danielebarchiesi@4
|
12 ARC2::inc('RDFSerializer');
|
danielebarchiesi@4
|
13
|
danielebarchiesi@4
|
14 class ARC2_RDFXMLSerializer extends ARC2_RDFSerializer {
|
danielebarchiesi@4
|
15
|
danielebarchiesi@4
|
16 function __construct($a, &$caller) {
|
danielebarchiesi@4
|
17 parent::__construct($a, $caller);
|
danielebarchiesi@4
|
18 }
|
danielebarchiesi@4
|
19
|
danielebarchiesi@4
|
20 function __init() {
|
danielebarchiesi@4
|
21 parent::__init();
|
danielebarchiesi@4
|
22 $this->content_header = 'application/rdf+xml';
|
danielebarchiesi@4
|
23 $this->pp_containers = $this->v('serializer_prettyprint_containers', 0, $this->a);
|
danielebarchiesi@4
|
24 $this->default_ns = $this->v('serializer_default_ns', '', $this->a);
|
danielebarchiesi@4
|
25 $this->type_nodes = $this->v('serializer_type_nodes', 0, $this->a);
|
danielebarchiesi@4
|
26 }
|
danielebarchiesi@4
|
27
|
danielebarchiesi@4
|
28 /* */
|
danielebarchiesi@4
|
29
|
danielebarchiesi@4
|
30 function getTerm($v, $type) {
|
danielebarchiesi@4
|
31 if (!is_array($v)) {/* uri or bnode */
|
danielebarchiesi@4
|
32 if (preg_match('/^\_\:(.*)$/', $v, $m)) {
|
danielebarchiesi@4
|
33 return ' rdf:nodeID="' . $m[1] . '"';
|
danielebarchiesi@4
|
34 }
|
danielebarchiesi@4
|
35 if ($type == 's') {
|
danielebarchiesi@4
|
36 return ' rdf:about="' . htmlspecialchars($v) . '"';
|
danielebarchiesi@4
|
37 }
|
danielebarchiesi@4
|
38 if ($type == 'p') {
|
danielebarchiesi@4
|
39 $pn = $this->getPName($v);
|
danielebarchiesi@4
|
40 return $pn ? $pn : 0;
|
danielebarchiesi@4
|
41 }
|
danielebarchiesi@4
|
42 if ($type == 'o') {
|
danielebarchiesi@4
|
43 $v = $this->expandPName($v);
|
danielebarchiesi@4
|
44 if (!preg_match('/^[a-z0-9]{2,}\:[^\s]+$/is', $v)) return $this->getTerm(array('value' => $v, 'type' => 'literal'), $type);
|
danielebarchiesi@4
|
45 return ' rdf:resource="' . htmlspecialchars($v) . '"';
|
danielebarchiesi@4
|
46 }
|
danielebarchiesi@4
|
47 if ($type == 'datatype') {
|
danielebarchiesi@4
|
48 $v = $this->expandPName($v);
|
danielebarchiesi@4
|
49 return ' rdf:datatype="' . htmlspecialchars($v) . '"';
|
danielebarchiesi@4
|
50 }
|
danielebarchiesi@4
|
51 if ($type == 'lang') {
|
danielebarchiesi@4
|
52 return ' xml:lang="' . htmlspecialchars($v) . '"';
|
danielebarchiesi@4
|
53 }
|
danielebarchiesi@4
|
54 }
|
danielebarchiesi@4
|
55 if ($this->v('type', '', $v) != 'literal') {
|
danielebarchiesi@4
|
56 return $this->getTerm($v['value'], 'o');
|
danielebarchiesi@4
|
57 }
|
danielebarchiesi@4
|
58 /* literal */
|
danielebarchiesi@4
|
59 $dt = isset($v['datatype']) ? $v['datatype'] : '';
|
danielebarchiesi@4
|
60 $lang = isset($v['lang']) ? $v['lang'] : '';
|
danielebarchiesi@4
|
61 if ($dt == 'http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral') {
|
danielebarchiesi@4
|
62 return ' rdf:parseType="Literal">' . $v['value'];
|
danielebarchiesi@4
|
63 }
|
danielebarchiesi@4
|
64 elseif ($dt) {
|
danielebarchiesi@4
|
65 return $this->getTerm($dt, 'datatype') . '>' . htmlspecialchars($v['value']);
|
danielebarchiesi@4
|
66 }
|
danielebarchiesi@4
|
67 elseif ($lang) {
|
danielebarchiesi@4
|
68 return $this->getTerm($lang, 'lang') . '>' . htmlspecialchars($v['value']);
|
danielebarchiesi@4
|
69 }
|
danielebarchiesi@4
|
70 return '>' . htmlspecialchars($this->v('value', '', $v));
|
danielebarchiesi@4
|
71 }
|
danielebarchiesi@4
|
72
|
danielebarchiesi@4
|
73 function getPName($v, $connector = ':') {
|
danielebarchiesi@4
|
74 if ($this->default_ns && (strpos($v, $this->default_ns) === 0)) {
|
danielebarchiesi@4
|
75 $pname = substr($v, strlen($this->default_ns));
|
danielebarchiesi@4
|
76 if (!preg_match('/\//', $pname)) return $pname;
|
danielebarchiesi@4
|
77 }
|
danielebarchiesi@4
|
78 return parent::getPName($v, $connector);
|
danielebarchiesi@4
|
79 }
|
danielebarchiesi@4
|
80
|
danielebarchiesi@4
|
81 function getHead() {
|
danielebarchiesi@4
|
82 $r = '';
|
danielebarchiesi@4
|
83 $nl = "\n";
|
danielebarchiesi@4
|
84 $r .= '<?xml version="1.0" encoding="UTF-8"?>';
|
danielebarchiesi@4
|
85 $r .= $nl . '<rdf:RDF';
|
danielebarchiesi@4
|
86 $first_ns = 1;
|
danielebarchiesi@4
|
87 foreach ($this->used_ns as $v) {
|
danielebarchiesi@4
|
88 $r .= $first_ns ? ' ' : $nl . ' ';
|
danielebarchiesi@4
|
89 foreach ($this->ns as $prefix => $ns) {
|
danielebarchiesi@4
|
90 if ($ns != $v) continue;
|
danielebarchiesi@4
|
91 $r .= 'xmlns:' . $prefix . '="' .$v. '"';
|
danielebarchiesi@4
|
92 break;
|
danielebarchiesi@4
|
93 }
|
danielebarchiesi@4
|
94 $first_ns = 0;
|
danielebarchiesi@4
|
95 }
|
danielebarchiesi@4
|
96 if ($this->default_ns) {
|
danielebarchiesi@4
|
97 $r .= $first_ns ? ' ' : $nl . ' ';
|
danielebarchiesi@4
|
98 $r .= 'xmlns="' . $this->default_ns . '"';
|
danielebarchiesi@4
|
99 }
|
danielebarchiesi@4
|
100 $r .= '>';
|
danielebarchiesi@4
|
101 return $r;
|
danielebarchiesi@4
|
102 }
|
danielebarchiesi@4
|
103
|
danielebarchiesi@4
|
104 function getFooter() {
|
danielebarchiesi@4
|
105 $r = '';
|
danielebarchiesi@4
|
106 $nl = "\n";
|
danielebarchiesi@4
|
107 $r .= $nl . $nl . '</rdf:RDF>';
|
danielebarchiesi@4
|
108 return $r;
|
danielebarchiesi@4
|
109 }
|
danielebarchiesi@4
|
110
|
danielebarchiesi@4
|
111 function getSerializedIndex($index, $raw = 0) {
|
danielebarchiesi@4
|
112 $r = '';
|
danielebarchiesi@4
|
113 $nl = "\n";
|
danielebarchiesi@4
|
114 foreach ($index as $raw_s => $ps) {
|
danielebarchiesi@4
|
115 $r .= $r ? $nl . $nl : '';
|
danielebarchiesi@4
|
116 $s = $this->getTerm($raw_s, 's');
|
danielebarchiesi@4
|
117 $tag = 'rdf:Description';
|
danielebarchiesi@4
|
118 list($tag, $ps) = $this->getNodeTag($ps);
|
danielebarchiesi@4
|
119 $sub_ps = 0;
|
danielebarchiesi@4
|
120 /* pretty containers */
|
danielebarchiesi@4
|
121 if ($this->pp_containers && ($ctag = $this->getContainerTag($ps))) {
|
danielebarchiesi@4
|
122 $tag = 'rdf:' . $ctag;
|
danielebarchiesi@4
|
123 list($ps, $sub_ps) = $this->splitContainerEntries($ps);
|
danielebarchiesi@4
|
124 }
|
danielebarchiesi@4
|
125 $r .= ' <' . $tag . '' .$s . '>';
|
danielebarchiesi@4
|
126 $first_p = 1;
|
danielebarchiesi@4
|
127 foreach ($ps as $p => $os) {
|
danielebarchiesi@4
|
128 if (!$os) continue;
|
danielebarchiesi@4
|
129 $p = $this->getTerm($p, 'p');
|
danielebarchiesi@4
|
130 if ($p) {
|
danielebarchiesi@4
|
131 $r .= $nl . str_pad('', 4);
|
danielebarchiesi@4
|
132 $first_o = 1;
|
danielebarchiesi@4
|
133 if (!is_array($os)) {/* single literal o */
|
danielebarchiesi@4
|
134 $os = array(array('value' => $os, 'type' => 'literal'));
|
danielebarchiesi@4
|
135 }
|
danielebarchiesi@4
|
136 foreach ($os as $o) {
|
danielebarchiesi@4
|
137 $o = $this->getTerm($o, 'o');
|
danielebarchiesi@4
|
138 $r .= $first_o ? '' : $nl . ' ';
|
danielebarchiesi@4
|
139 $r .= '<' . $p;
|
danielebarchiesi@4
|
140 $r .= $o;
|
danielebarchiesi@4
|
141 $r .= preg_match('/\>/', $o) ? '</' . $p . '>' : '/>';
|
danielebarchiesi@4
|
142 $first_o = 0;
|
danielebarchiesi@4
|
143 }
|
danielebarchiesi@4
|
144 $first_p = 0;
|
danielebarchiesi@4
|
145 }
|
danielebarchiesi@4
|
146 }
|
danielebarchiesi@4
|
147 $r .= $r ? $nl . ' </' . $tag . '>' : '';
|
danielebarchiesi@4
|
148 if ($sub_ps) $r .= $nl . $nl . $this->getSerializedIndex(array($raw_s => $sub_ps), 1);
|
danielebarchiesi@4
|
149 }
|
danielebarchiesi@4
|
150 if ($raw) {
|
danielebarchiesi@4
|
151 return $r;
|
danielebarchiesi@4
|
152 }
|
danielebarchiesi@4
|
153 return $this->getHead() . $nl . $nl . $r . $this->getFooter();
|
danielebarchiesi@4
|
154 }
|
danielebarchiesi@4
|
155
|
danielebarchiesi@4
|
156 function getNodeTag($ps) {
|
danielebarchiesi@4
|
157 if (!$this->type_nodes) return array('rdf:Description', $ps);
|
danielebarchiesi@4
|
158 $rdf = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
|
danielebarchiesi@4
|
159 $types = $this->v($rdf . 'type', array(), $ps);
|
danielebarchiesi@4
|
160 if (!$types) return array('rdf:Description', $ps);
|
danielebarchiesi@4
|
161 $type = array_shift($types);
|
danielebarchiesi@4
|
162 $ps[$rdf . 'type'] = $types;
|
danielebarchiesi@4
|
163 if (!is_array($type)) $type = array('value' => $type);
|
danielebarchiesi@4
|
164 return array($this->getPName($type['value']), $ps);
|
danielebarchiesi@4
|
165 }
|
danielebarchiesi@4
|
166
|
danielebarchiesi@4
|
167 /* */
|
danielebarchiesi@4
|
168
|
danielebarchiesi@4
|
169 function getContainerTag($ps) {
|
danielebarchiesi@4
|
170 $rdf = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
|
danielebarchiesi@4
|
171 if (!isset($ps[$rdf . 'type'])) return '';
|
danielebarchiesi@4
|
172 $types = $ps[$rdf . 'type'];
|
danielebarchiesi@4
|
173 foreach ($types as $type) {
|
danielebarchiesi@4
|
174 if (!in_array($type['value'], array($rdf . 'Bag', $rdf . 'Seq', $rdf . 'Alt'))) return '';
|
danielebarchiesi@4
|
175 return str_replace($rdf, '', $type['value']);
|
danielebarchiesi@4
|
176 }
|
danielebarchiesi@4
|
177 }
|
danielebarchiesi@4
|
178
|
danielebarchiesi@4
|
179 function splitContainerEntries($ps) {
|
danielebarchiesi@4
|
180 $rdf = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
|
danielebarchiesi@4
|
181 $items = array();
|
danielebarchiesi@4
|
182 $rest = array();
|
danielebarchiesi@4
|
183 foreach ($ps as $p => $os) {
|
danielebarchiesi@4
|
184 $p_short = str_replace($rdf, '', $p);
|
danielebarchiesi@4
|
185 if ($p_short === 'type') continue;
|
danielebarchiesi@4
|
186 if (preg_match('/^\_([0-9]+)$/', $p_short, $m)) {
|
danielebarchiesi@4
|
187 $items = array_merge($items, $os);
|
danielebarchiesi@4
|
188 }
|
danielebarchiesi@4
|
189 else {
|
danielebarchiesi@4
|
190 $rest[$p] = $os;
|
danielebarchiesi@4
|
191 }
|
danielebarchiesi@4
|
192 }
|
danielebarchiesi@4
|
193 if ($items) return array(array($rdf . 'li' => $items), $rest);
|
danielebarchiesi@4
|
194 return array($rest, 0);
|
danielebarchiesi@4
|
195 }
|
danielebarchiesi@4
|
196
|
danielebarchiesi@4
|
197 /* */
|
danielebarchiesi@4
|
198 }
|