diff --git a/module/VuFind/src/VuFind/Harvester/OAI.php b/module/VuFind/src/VuFind/Harvester/OAI.php index 6af9abdc6ddc5c03d615890f4582ee6cf16508ed..abca82954f1a422c90fdc2bc638119d39f7ad753 100644 --- a/module/VuFind/src/VuFind/Harvester/OAI.php +++ b/module/VuFind/src/VuFind/Harvester/OAI.php @@ -564,7 +564,8 @@ class OAI // there is probably a cleaner way to do this, but this simple method avoids // the complexity of dealing with namespaces in SimpleXML: $xml = trim($record->metadata->asXML()); - $xml = preg_replace('/(^<metadata>)|(<\/metadata>$)/m', '', $xml); + preg_match('/^<metadata([^\>]*)>/', $xml, $extractedNs); + $xml = preg_replace('/(^<metadata[^\>]*>)|(<\/metadata>$)/m', '', $xml); // If we are supposed to inject any values, do so now inside the first // tag of the file: @@ -607,11 +608,41 @@ class OAI if (!empty($insert)) { $xml = preg_replace('/>/', '>' . $insert, $xml, 1); } + $xml = $this->fixNamespaces( + $xml, $record->getDocNamespaces(), + isset($extractedNs[1]) ? $extractedNs[1] : '' + ); // Save our XML: file_put_contents($this->getFilename($id, 'xml'), trim($xml)); } + /** + * Support method for saveRecord() -- fix namespaces in the top tag of the XML + * document to compensate for bugs in the SimpleXML library. + * + * @param string $xml XML document to clean up + * @param array $ns Namespaces to check + * @param string $attr Attributes extracted from the <metadata> tag + * + * @return string + */ + protected function fixNamespaces($xml, $ns, $attr = '') + { + foreach ($ns as $key => $val) { + if (!empty($key) + && strstr($xml, $key . ':') && !strstr($xml, 'xmlns:' . $key) + && !strstr($attr, 'xmlns:' . $key) + ) { + $attr .= ' xmlns:' . $key . '="' . $val . '"'; + } + } + if (!empty($attr)) { + $xml = preg_replace('/>/', $attr . '>', $xml, 1); + } + return $xml; + } + /** * Load date granularity from the server. * @@ -668,7 +699,7 @@ class OAI } /** - * Extract the ID from a record object (support method for _processRecords()). + * Extract the ID from a record object (support method for processRecords()). * * @param object $record SimpleXML record. *