1use Test::More tests => 22; 2use Test::Exception; 3 4use strict; 5use warnings; 6no warnings 'redefine'; 7 8use RDF::Trine qw(iri statement); 9use_ok('RDF::Trine::Serializer::RDFXML'); 10 11 12{ 13 my $model = RDF::Trine::Model->temporary_model; 14 $model->add_hashref({ 15 'http://example.com/doc' => { 16 'http://example.com/predicate' => [ 17 {'type' => 'literal','value' => 'Foo'}, 18 {'type' => 'uri','value' => 'http://example.com/bar'}, 19 'baz@en' 20 ], 21 }, 22 }); 23 24 my $serializer = RDF::Trine::Serializer::RDFXML->new(); 25 my $expect = <<"END"; 26<?xml version="1.0" encoding="utf-8"?> 27<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 28<rdf:Description xmlns:ns1="http://example.com/" rdf:about="http://example.com/doc"> 29 <ns1:predicate rdf:resource="http://example.com/bar"/> 30 <ns1:predicate>Foo</ns1:predicate> 31 <ns1:predicate xml:lang="en">baz</ns1:predicate> 32</rdf:Description> 33</rdf:RDF> 34END 35 36 { 37 my $xml = $serializer->serialize_model_to_string($model); 38 is($xml, $expect, 'serialize_model_to_string 1'); 39 } 40 { 41 my $iter = $model->as_stream; 42 my $xml = $serializer->serialize_iterator_to_string($iter); 43 is($xml, $expect, 'serialize_iterator_to_string 1'); 44 } 45} 46 47{ 48 my $model = RDF::Trine::Model->temporary_model; 49 $model->add_hashref({ 50 './doc' => { 51 './predicate' => [ 52 {'type' => 'literal','value' => 'Foo'}, 53 {'type' => 'uri','value' => './bar'}, 54 'baz@en' 55 ], 56 }, 57 }); 58 59 my $serializer = RDF::Trine::Serializer::RDFXML->new( base_uri => 'http://example.org/'); 60 my $expect = <<"END"; 61<?xml version="1.0" encoding="utf-8"?> 62<rdf:RDF xml:base="http://example.org/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 63<rdf:Description xmlns:ns1="./" rdf:about="./doc"> 64 <ns1:predicate rdf:resource="./bar"/> 65 <ns1:predicate>Foo</ns1:predicate> 66 <ns1:predicate xml:lang="en">baz</ns1:predicate> 67</rdf:Description> 68</rdf:RDF> 69END 70 71 { 72 my $xml = $serializer->serialize_model_to_string($model); 73 is($xml, $expect, 'serialize_model_to_string 1'); 74 } 75} 76 77{ 78 my $model = RDF::Trine::Model->temporary_model; 79 $model->add_hashref({ 80 '_:b' => { 81 'http://example.com/ns#description' => ['quux'], 82 }, 83 }); 84 85 my $serializer = RDF::Trine::Serializer::RDFXML->new(); 86 my $xml = $serializer->serialize_model_to_string($model); 87 88 is($xml, <<"END", 'serialize_model_to_string 2: simple literal'); 89<?xml version="1.0" encoding="utf-8"?> 90<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 91<rdf:Description xmlns:ns1="http://example.com/ns#" rdf:nodeID="b"> 92 <ns1:description>quux</ns1:description> 93</rdf:Description> 94</rdf:RDF> 95END 96} 97 98{ 99 my $model = RDF::Trine::Model->temporary_model; 100 $model->add_hashref({ 101 '_:a' => { 102 'http://example.com/ns#title' => [ 103 'foo', 104 {type => 'literal', value => 'bar', datatype => 'http://www.w3.org/2001/XMLSchema#string'}, 105 ], 106 }, 107 }); 108 109 my $serializer = RDF::Trine::Serializer::RDFXML->new(); 110 my $xml = $serializer->serialize_model_to_string($model); 111 112 is($xml, <<"END", 'serialize_model_to_string 3: datatype literal'); 113<?xml version="1.0" encoding="utf-8"?> 114<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 115<rdf:Description xmlns:ns1="http://example.com/ns#" rdf:nodeID="a"> 116 <ns1:title rdf:datatype="http://www.w3.org/2001/XMLSchema#string">bar</ns1:title> 117 <ns1:title>foo</ns1:title> 118</rdf:Description> 119</rdf:RDF> 120END 121} 122 123{ 124 my $model = RDF::Trine::Model->temporary_model; 125 $model->add_hashref({ 126 '_:b' => { 127 'http://example.com/ns#description' => [{type=>'uri', value=>'_:a'}], 128 }, 129 }); 130 131 my $serializer = RDF::Trine::Serializer::RDFXML->new(); 132 my $xml = $serializer->serialize_model_to_string($model); 133 134 is($xml, <<"END", 'serialize_model_to_string 4: blank object'); 135<?xml version="1.0" encoding="utf-8"?> 136<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 137<rdf:Description xmlns:ns1="http://example.com/ns#" rdf:nodeID="b"> 138 <ns1:description rdf:nodeID="a"/> 139</rdf:Description> 140</rdf:RDF> 141END 142} 143 144{ 145 my $model = RDF::Trine::Model->temporary_model; 146 $model->add_hashref({ 147 'http://example.com/alice' => { 148 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => [{ type => 'resource', value => 'http://xmlns.com/foaf/0.1/Person' }], 149 'http://purl.org/net/inkel/rdf/schemas/lang/1.1#masters' => ['en'], 150 'http://xmlns.com/foaf/0.1/name' => [ 'Alice', {'type' => 'literal','value' => 'Alice', language => 'en' } ], 151 }, 152 }); 153 154 my $serializer = RDF::Trine::Serializer::RDFXML->new(); 155 my $expect = <<"END"; 156<?xml version="1.0" encoding="utf-8"?> 157<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 158<rdf:Description xmlns:ns1="http://purl.org/net/inkel/rdf/schemas/lang/1.1#" xmlns:ns2="http://xmlns.com/foaf/0.1/" rdf:about="http://example.com/alice"> 159 <ns1:masters>en</ns1:masters> 160 <rdf:type rdf:resource="http://xmlns.com/foaf/0.1/Person"/> 161 <ns2:name>Alice</ns2:name> 162</rdf:Description> 163</rdf:RDF> 164END 165 166 my $xml = $serializer->serialize_model_to_string($model); 167 is($xml, $expect, 'serialize_model_to_string 5: multiple namespaces'); 168} 169 170{ 171 my $model = RDF::Trine::Model->temporary_model; 172 $model->add_hashref({ 173 '_:b' => { 174 'http://example.com/' => [{type=>'uri', value=>'_:a'}], 175 }, 176 }); 177 178 my $serializer = RDF::Trine::Serializer::RDFXML->new(); 179 throws_ok { 180 my $xml = $serializer->serialize_model_to_string($model); 181 } 'RDF::Trine::Error::SerializationError', "serializing bad predicates throws exception (uri ends with '/')"; 182} 183 184{ 185 my $model = RDF::Trine::Model->temporary_model; 186 $model->add_hashref({ 187 '_:b' => { 188 'http://example.com/123' => [{type=>'uri', value=>'_:a'}], 189 }, 190 }); 191 192 my $serializer = RDF::Trine::Serializer::RDFXML->new(); 193 throws_ok { 194 my $xml = $serializer->serialize_model_to_string($model); 195 warn $xml; 196 } 'RDF::Trine::Error::SerializationError', "serializing bad predicates throws exception (local part starts with digits)"; 197} 198 199{ 200 my $model = RDF::Trine::Model->temporary_model; 201 $model->add_hashref({ 202 'http://example.com/doc' => { 203 'http://example.com/predicate' => [ 204 {'type' => 'literal','value' => 'Foo'}, 205 {'type' => 'uri','value' => 'http://example.com/bar'}, 206 'baz@en' 207 ], 208 }, 209 'http://example.com/bar' => { 210 'http://example.com/predicate' => [ 211 {'type' => 'literal','value' => 'Bar'}, 212 ], 213 }, 214 }); 215 216 my $serializer = RDF::Trine::Serializer::RDFXML->new(); 217 my $expect = <<"END"; 218<?xml version="1.0" encoding="utf-8"?> 219<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 220<rdf:Description xmlns:ns1="http://example.com/" rdf:about="http://example.com/bar"> 221 <ns1:predicate>Bar</ns1:predicate> 222</rdf:Description> 223<rdf:Description xmlns:ns1="http://example.com/" rdf:about="http://example.com/doc"> 224 <ns1:predicate rdf:resource="http://example.com/bar"/> 225 <ns1:predicate>Foo</ns1:predicate> 226 <ns1:predicate xml:lang="en">baz</ns1:predicate> 227</rdf:Description> 228</rdf:RDF> 229END 230 231 { 232 my $xml = $serializer->serialize_model_to_string($model); 233 is($xml, $expect, 'serialize_model_to_string 1'); 234 } 235 { 236 my $iter = $model->as_stream; 237 my $xml = $serializer->serialize_iterator_to_string($iter); 238 is($xml, $expect, 'serialize_iterator_to_string 1'); 239 } 240} 241 242{ 243 my $model = RDF::Trine::Model->temporary_model; 244 $model->add_hashref({ 245 'http://example.com/doc' => { 246 'http://example.com/maker' => [ 247 {'type' => 'uri','value' => '_:a'}, 248 ], 249 }, 250 '_:a' => { 251 'http://example.com/name' => [ 252 {'type' => 'literal','value' => 'Alice', 'lang' => 'en'}, 253 ], 254 'http://example.com/homepage' => [ 255 {'type' => 'uri', 'value' => 'http://example.com/' }, 256 ], 257 }, 258 }); 259 260 my $serializer = RDF::Trine::Serializer::RDFXML->new(); 261 my $expect = <<"END"; 262<?xml version="1.0" encoding="utf-8"?> 263<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 264<rdf:Description xmlns:ns1="http://example.com/" rdf:about="http://example.com/doc"> 265 <ns1:maker rdf:nodeID="a"/> 266</rdf:Description> 267<rdf:Description xmlns:ns1="http://example.com/" rdf:nodeID="a"> 268 <ns1:homepage rdf:resource="http://example.com/"/> 269 <ns1:name xml:lang="en">Alice</ns1:name> 270</rdf:Description> 271</rdf:RDF> 272END 273 274 my $iter = $model->bounded_description( iri('http://example.com/doc') ); 275 my $xml = $serializer->serialize_iterator_to_string( $iter ); 276 is($xml, $expect, 'serialize bounded description 1'); 277} 278 279{ 280 my $model = RDF::Trine::Model->temporary_model; 281 $model->add_hashref({ 282 'http://example.com/doc' => { 283 'http://example.com/maker' => [ 284 {'type' => 'uri','value' => '_:a'}, 285 ], 286 'http://example.com/creator' => [ 287 {'type' => 'uri','value' => '_:a'}, 288 ], 289 }, 290 '_:a' => { 291 'http://example.com/name' => [ 292 {'type' => 'literal','value' => 'Alice', 'lang' => 'en'}, 293 ], 294 'http://example.com/homepage' => [ 295 {'type' => 'uri', 'value' => 'http://example.com/' }, 296 ], 297 }, 298 }); 299 300 my $serializer = RDF::Trine::Serializer::RDFXML->new(); 301 my $expect = <<"END"; 302<?xml version="1.0" encoding="utf-8"?> 303<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 304<rdf:Description xmlns:ns1="http://example.com/" rdf:about="http://example.com/doc"> 305 <ns1:creator rdf:nodeID="a"/> 306 <ns1:maker rdf:nodeID="a"/> 307</rdf:Description> 308<rdf:Description xmlns:ns1="http://example.com/" rdf:nodeID="a"> 309 <ns1:homepage rdf:resource="http://example.com/"/> 310 <ns1:name xml:lang="en">Alice</ns1:name> 311</rdf:Description> 312</rdf:RDF> 313END 314 315 my $iter = $model->bounded_description( iri('http://example.com/doc') ); 316 my $xml = $serializer->serialize_iterator_to_string( $iter ); 317 is($xml, $expect, 'serialize bounded description 2'); 318} 319 320{ 321 my $model = RDF::Trine::Model->temporary_model; 322 $model->add_hashref({ 323 'http://example.com/doc' => { 324 'http://example.com/maker' => [ 325 {'type' => 'uri','value' => '_:a'}, 326 ], 327 'http://example.com/creator' => [ 328 {'type' => 'uri','value' => '_:a'}, 329 ], 330 }, 331 '_:a' => { 332 'http://example.com/name' => [ 333 {'type' => 'literal','value' => 'Alice', 'lang' => 'en'}, 334 ], 335 'http://example.com/homepage' => [ 336 {'type' => 'uri', 'value' => 'http://example.com/' }, 337 ], 338 }, 339 }); 340 341 my $serializer = RDF::Trine::Serializer::RDFXML->new(); 342 my $expect = <<"END"; 343<?xml version="1.0" encoding="utf-8"?> 344<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 345</rdf:RDF> 346END 347 348 my $iter = $model->bounded_description( iri('http://example.com/unknown') ); 349 my $xml = $serializer->serialize_iterator_to_string( $iter ); 350 is($xml, $expect, 'serialize bounded description with unknown node'); 351} 352 353{ 354 my $model = RDF::Trine::Model->temporary_model(); 355 my $serializer = RDF::Trine::Serializer::RDFXML->new(); 356 my $expect = <<"END"; 357<?xml version="1.0" encoding="utf-8"?> 358<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 359</rdf:RDF> 360END 361 362 my $xml = $serializer->serialize_model_to_string($model); 363 is($xml, $expect, 'serialize_model_to_string with empty model'); 364} 365 366{ 367 my $serializer = RDF::Trine::Serializer::RDFXML->new( namespaces => { ex => 'http://example.com/' } ); 368 my $model = RDF::Trine::Model->temporary_model; 369 $model->add_hashref({ 370 'http://example.com/doc' => { 371 'http://example.com/maker' => [ 372 {'type' => 'uri','value' => '_:a'}, 373 ], 374 }, 375 '_:a' => { 376 'http://example.com/name' => [ 377 {'type' => 'literal','value' => 'Alice', 'lang' => 'en'}, 378 ], 379 'http://example.com/homepage' => [ 380 {'type' => 'uri', 'value' => 'http://example.com/' }, 381 ], 382 }, 383 }); 384 385 my $expect = <<"END"; 386<?xml version="1.0" encoding="utf-8"?> 387<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:ex="http://example.com/"> 388<rdf:Description rdf:about="http://example.com/doc"> 389 <ex:maker rdf:nodeID="a"/> 390</rdf:Description> 391<rdf:Description rdf:nodeID="a"> 392 <ex:homepage rdf:resource="http://example.com/"/> 393 <ex:name xml:lang="en">Alice</ex:name> 394</rdf:Description> 395</rdf:RDF> 396END 397 398 my $iter = $model->bounded_description( iri('http://example.com/doc') ); 399 my $xml = $serializer->serialize_iterator_to_string( $iter ); 400 is($xml, $expect, 'xmlns namespaces 1'); 401} 402 403{ 404 my $serializer = RDF::Trine::Serializer::RDFXML->new( namespaces => { 405 foaf => 'http://xmlns.com/foaf/0.1/', 406 rdfs => "http://www.w3.org/2000/01/rdf-schema#", 407 lang => "http://purl.org/net/inkel/rdf/schemas/lang/1.1#", 408 } ); 409 my $model = RDF::Trine::Model->temporary_model; 410 $model->add_hashref({ 411 '_:a' => { 412 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => [{type => 'uri', value => 'http://xmlns.com/foaf/0.1/Person'}], 413 'http://xmlns.com/foaf/0.1/name' => ['Eve'], 414 'http://purl.org/net/inkel/rdf/schemas/lang/1.1#masters' => ['en','fr'], 415 'http://www.w3.org/2000/01/rdf-schema#seeAlso' => [{type => 'uri', value => 'http://eve.example.com/'}], 416 }, 417 }); 418 419 my $xml = $serializer->serialize_model_to_string($model); 420 like( $xml, qr[xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:foaf="http://xmlns.com/foaf/0.1/" xmlns:lang="http://purl.org/net/inkel/rdf/schemas/lang/1.1#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"]sm, 'xmlns sorted in rdf:RDF tag' ); 421 like( $xml, qr[<lang:masters>en</lang:masters>]sm, 'Qname literal tag' ); 422 like( $xml, qr[<rdfs:seeAlso rdf:resource="http://eve.example.com/"/>]sm, 'Qname resource tag' ); 423} 424 425{ 426 my $serializer = RDF::Trine::Serializer::RDFXML->new(); 427 my $model = RDF::Trine::Model->temporary_model; 428 my $base_uri = 'http://example.org/'; 429 my $url_with_amp = "$base_uri?foo=bar&doz=baz"; 430 $model->add_statement( statement( iri($base_uri), iri("http://xmlns.com/foaf/0.1/page"), iri($url_with_amp) ) ); 431 432 my $xml = $serializer->serialize_model_to_string($model); 433 like( $xml, qr[&]sm, 'XML entity escaping' ); 434} 435 436{ 437 my $serializer = RDF::Trine::Serializer::RDFXML->new( scoped_namespaces => 1, namespaces => { ex => 'http://example.com/', unused1 => 'http://example.org/not-used', unused2 => 'tag:kasei.us,2012-01-01:' } ); 438 my $model = RDF::Trine::Model->temporary_model; 439 $model->add_hashref({ 440 'http://example.com/doc' => { 441 'http://example.com/maker' => [ 442 {'type' => 'uri','value' => '_:a'}, 443 ], 444 }, 445 '_:a' => { 446 'http://example.com/name' => [ 447 {'type' => 'literal','value' => 'Alice', 'lang' => 'en'}, 448 ], 449 'http://example.com/homepage' => [ 450 {'type' => 'uri', 'value' => 'http://example.com/' }, 451 ], 452 }, 453 }); 454 455 my $expect = <<"END"; 456<?xml version="1.0" encoding="utf-8"?> 457<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 458<rdf:Description rdf:about="http://example.com/doc"> 459 <ex:maker xmlns:ex="http://example.com/" rdf:nodeID="a"/> 460</rdf:Description> 461<rdf:Description rdf:nodeID="a"> 462 <ex:homepage xmlns:ex="http://example.com/" rdf:resource="http://example.com/"/> 463 <ex:name xmlns:ex="http://example.com/" xml:lang="en">Alice</ex:name> 464</rdf:Description> 465</rdf:RDF> 466END 467 468 my $iter = $model->bounded_description( iri('http://example.com/doc') ); 469 my $xml = $serializer->serialize_iterator_to_string( $iter ); 470 is($xml, $expect, 'xmlns namespaces 2 with unused definitions'); 471} 472