From 838ea92fcd0b9f52c4597d99e237b17fc235ffe8 Mon Sep 17 00:00:00 2001 From: Hector Castro Date: Tue, 17 Feb 2015 11:15:04 -0600 Subject: [PATCH 2/2] Bug 13642 [ENH] Adding new features for Dublin Core metadata When Koha export a bibliographic record to DC, makes it in XML format. This XML is not well-formed document and do not follows the DC-XML recommendations as should be. New feature, adds an ability to export Dublin Core metadata to XML and RDF (including rdfxml, rdfjson, ntriples, turtle, etc.) Test plan --------------- 1) Download Dublin Core file. Open up the file, and make sure that the document is not well formed 2) Apply patch. 3) Go to whichever bib record in OPAC or staff and click on Save > Dublin Core. A modal will display, prove all options. 4) Change the system preference 'Opac ExportOptions' by enabling and disabling Dublin Core and try to download a record in the OPAC. 5) Try several bibliographic records in any format (book, magazine, DVD, etc.) to confirm that properly exported. 6) RDF/XML can be validated per RDF Validator W3C and OAI-DC can be validated by other validator. Sponsored-by: Universidad de El Salvador Signed-off-by: Hector Castro XML::Entities not found in .deb package New patch for work with librdf-helper-perl (2.0) and librdf-trine-perl (1.000). RDF::Trine and RDF::Helper not need to be upgraded. Tested in both (upgraded and not upgraded) Fix some utf8 encoding. --- C4/Installer/PerlDependencies.pm | 4 +- Koha/DublinCoreTransformer.pm | 76 ++++++++++++++++++++++++++++++-------- 2 files changed, 62 insertions(+), 18 deletions(-) mode change 100755 => 100644 C4/Installer/PerlDependencies.pm diff --git a/C4/Installer/PerlDependencies.pm b/C4/Installer/PerlDependencies.pm old mode 100755 new mode 100644 index 8b0fd73..1f0111f --- a/C4/Installer/PerlDependencies.pm +++ b/C4/Installer/PerlDependencies.pm @@ -750,12 +750,12 @@ our $PERL_DEPS = { 'RDF::Trine' => { 'usage' => 'Core', 'required' => '1', - 'min_ver' => '1.012', + 'min_ver' => '1.000', }, 'RDF::Helper' => { 'usage' => 'Core', 'required' => '1', - 'min_ver' => '2.01', + 'min_ver' => '2.0', }, }; diff --git a/Koha/DublinCoreTransformer.pm b/Koha/DublinCoreTransformer.pm index 57c16b0..6439d7f 100644 --- a/Koha/DublinCoreTransformer.pm +++ b/Koha/DublinCoreTransformer.pm @@ -45,7 +45,7 @@ BEGIN { } -use Encode qw(encode decode); +use Encode qw(is_utf8 encode decode); use MARC::File::USMARC; use MARC::Crosswalk::DublinCore; use XML::LibXML; @@ -258,9 +258,16 @@ sub write_xml { if ( $dataxml->{'entities'} == 1 ) { my @xml = $doc->toString(1); foreach (@xml) { - my ($dcxml_entity_encoded) = - XML_entity_encode( Encode::decode( 'UTF-8', $_ ) ); - $xml[-1] = $dcxml_entity_encoded; + my $enc = Encode::find_encoding('utf-8'); + if ( Encode::is_utf8( $_ ) ) { + my ($dcxml_entity_encoded) = + XML_entity_encode( $_ ); + $xml[-1] = $dcxml_entity_encoded; + } elsif ( $enc ) { + my ($dcxml_entity_encoded) = + XML_entity_encode( $enc->decode( $_ ) ); + $xml[-1] = $dcxml_entity_encoded; + } } my $xmljoiner = join "", @xml; return $xmljoiner; @@ -332,9 +339,16 @@ sub write_rdf { { my @xml = $rdf->serialize( format => $rdfdescription->{'rdf_format'} ); foreach (@xml) { - my ($dcxml_entity_encoded) = - XML_entity_encode( Encode::decode( 'UTF-8', $_ ) ); - $xml[-1] = $dcxml_entity_encoded; + my $enc = Encode::find_encoding('utf-8'); + if ( Encode::is_utf8( $_ ) ) { + my ($dcxml_entity_encoded) = + XML_entity_encode( $_ ); + $xml[-1] = $dcxml_entity_encoded; + } elsif ( $enc ) { + my ($dcxml_entity_encoded) = + XML_entity_encode( $enc->decode( $_ ) ); + $xml[-1] = $dcxml_entity_encoded; + } } my $xmljoiner = join "", @xml; return $xmljoiner; @@ -342,7 +356,8 @@ sub write_rdf { elsif ( $rdfdescription->{'rdf_format'} eq 'rdfjson' ) { my $encoding = $rdf->serialize( format => $rdfdescription->{'rdf_format'} ); - $encoding = Encode::encode( 'UTF-8', $encoding ); + my $enc = Encode::find_encoding('iso-8859-1'); + Encode::is_utf8 ( $encoding ) ? $encoding : $enc->decode ( $encoding ); return $encoding; } else { @@ -524,24 +539,26 @@ sub rdf_constructor { $deletespaces =~ s/\s//; my $predicate = 'dcterms:' . $lowercase; my $object = $element_content; - given ($element_scheme) { - when ( $element_scheme ne "DCMI Type Vocabulary" ) { + SWITCH: + for ($element_scheme) { + if ( /^ISO 3166/ ) { # Dublin core returns DCMI Type Vocabulary # This will do something like: - # + # # # us # - # - my $bnode = $rdf->new_bnode($deletespaces); + # + my $bnode = $rdf->new_bnode("country"); my $uri_resource = join "", $qualified, $deletespaces; my $resource = $rdf->new_resource($uri_resource); $rdf->assert_literal( $subject, $predicate, $bnode ); $rdf->assert_literal( $bnode, 'dcam:memberOf', $resource ); $rdf->assert_literal( $bnode, 'rdf:value', $object ); + last SWITCH; } - when ( $element_scheme eq "DCMI Type Vocabulary" ) + if ( /^DCMI Type Vocabulary/ ) { #Changing for DCMIType my $bnode = $rdf->new_bnode('DCMIType'); my $uri_resource = $qualified . 'DCMIType'; @@ -550,6 +567,34 @@ sub rdf_constructor { $rdf->assert_literal( $bnode, 'dcam:memberOf', $resource ); $rdf->assert_literal( $bnode, 'rdf:value', $object ); } + if ( /^ISO 639-2/ ) + { #Changing bnodeId ISO639-2 for language + my $bnode = $rdf->new_bnode('language'); + my $uri_resource = join "", $qualified, $deletespaces; + my $resource = $rdf->new_resource($uri_resource); + $rdf->assert_literal( $subject, $predicate, $bnode ); + $rdf->assert_literal( $bnode, 'dcam:memberOf', $resource ); + $rdf->assert_literal( $bnode, 'rdf:value', $object ); + } + if ( /^RFC 1766/ ) + { #Changing bnodeId RFC1766 for languagetag + my $bnode = $rdf->new_bnode('languagetag'); + my $uri_resource = join "", $qualified, $deletespaces; + my $resource = $rdf->new_resource($uri_resource); + $rdf->assert_literal( $subject, $predicate, $bnode ); + $rdf->assert_literal( $bnode, 'dcam:memberOf', $resource ); + $rdf->assert_literal( $bnode, 'rdf:value', $object ); + } + if ( /^LCSH/ || /^MeSH/ || /^LCC/ || /^DDC/ || + /^UDC/ || /^IMT/ || /^URI/ || /^TGN/ ) + { #Scheme sharing common elements + my $bnode = $rdf->new_bnode($deletespaces); + my $uri_resource = join "", $qualified, $deletespaces; + my $resource = $rdf->new_resource($uri_resource); + $rdf->assert_literal( $subject, $predicate, $bnode ); + $rdf->assert_literal( $bnode, 'dcam:memberOf', $resource ); + $rdf->assert_literal( $bnode, 'rdf:value', $object ); + } } } #if-elsif return $rdf; @@ -750,7 +795,7 @@ into metadata in XML or RDF format. #Or if you want to generate a file open (OUTPUT, '> dc2xml.xml') or die $!; - print OUTPUT print $XML-DC; + print OUTPUT $XML-DC; close(OUTPUT); =head2 DC-RDF @@ -783,7 +828,6 @@ into metadata in XML or RDF format. my $XML-RDF = $objectDC->write_rdf(); print $XML-RDF; - #Close the file according to MARC::File::USMARC $batch->close(); undef $marc; -- 1.7.10.4