-
-
Notifications
You must be signed in to change notification settings - Fork 489
Metadata Massive Replace
Date | Apr 22 2014 | Contacts | Jose García/Juan Luis Rodríguez |
Status | Motion passed / Done | Release | 2.12 |
Resources | Available | Ticket # | https://github.com/geonetwork/core-geonetwork/issues/471 |
Source code | https://github.com/geonetwork/core-geonetwork/pull/472 | ||
Funding | Ontario Ministry of Natural Resources (OMNR), Environment Canada |
This proposal adds a new feature to apply a massive replacement process in the content of metadata records selection. The feature is focussed in iso19139 metadata, but can be extended in the future to other non iso19139 profiles.
The user can select a set of metadata records and define the replacements to apply from a predefined list of fields classified in sections:
The feature allows to test the replacements before applying them, getting a report with all the metadata records updated and the individual change(s) applied to each metadata.
Other approach for massive update can be to use XLinks to reference contacts and other sections in the metadata that can require massive updates for example if a phone number changes or the responsible of the metadata leaves the organisation, but not always is an option for users to use XLinks.
The Massive replacements have been integrated in the Administration panel, in Tools > Batch process:
![Metadata massive replace form - Angular UI] (https://raw.githubusercontent.com/geonetwork/wiki_images/master/proposals/metadata-massive-replace/metadata-massive-replace-form-angularui.png)
![Metadata massive replace report - Angular UI] (https://raw.githubusercontent.com/geonetwork/wiki_images/master/proposals/metadata-massive-replace/metadata-massive-replace-report-angularui.png)
The feature works as described in the previous section for the ExtJS widgets UI.
The list of fields to replace is defined in a translations file using this format (field key, field label). These elements are used to build the user interface:
<section id="Metadata">
<field key="id.contact.individualName">Contact > Individual Name</field>
<field key="id.contact.organisationName">Contact > Organization Name</field>
... more fields
</section>
<section id="Identification">
<field key="id.dataid.abstract">Data Identification > Abstract</field>
<field key="id.dataid.purpose">Data Identification > Purpose</field>
... more fields
</section>
web-ui/src/main/resources/catalog/config/batch-process-cfg.json
Added a new property type
with these possible values:
- fixed-params: value used for existing processes.
{
"key": "contact-updater",
"type": "fixed-params",
"params": [
{"name": "emailToSearch", "value": "", "type": "email"},
{"name": "contactAsXML", "value": "", "type": "textarea"}
]
}
- template: value used for the batch replacement process. This value allows to configure the templates that handle the UI for the process.
{
"key": "batch-replacer",
"type": "template",
"template": "../../catalog/templates/admin/tools/batch-replacer.html",
"reportTemplate": "../../catalog/templates/admin/tools/batch-replacer-report.html"
}
web-ui/src/main/resources/catalog/templates/admin/tools/batch.html
: Added code to handle the processes with custom templates:
<!-- Render the process UI -->
<div data-ng-switch="selectedProcess.type">
<!-- fixed-params: render the parameters defined for the process -->
<div data-ng-switch-when="fixed-params">
<div data-ng-repeat="p in selectedProcess.params track by $index" data-ng-switch=""
data-on="p.type" class="form-group">
...
</div>
</div>
<!-- Render the template with the process UI -->
<div data-ng-switch-when="template">
<div data-ng-include="selectedProcess.template">
</div>
</div>
</div>
<!-- Render of the process report -->
<div data-ng-switch="selectedProcess.type">
<div class="col-lg-12" data-ng-hide="!processing && !processReport" id="gn-batch-process-report" data-ng-switch-when="fixed-params">
...
</div>
<div data-ng-switch-when="template">
<div data-ng-include="selectedProcess.reportTemplate">
</div>
</div>
</div>
web-ui/src/main/resources/catalog/js/admin/AdminToolsController.js
: Defines the packages/elements for the replacements.
$scope.batchReplacerGroups = {
"metadata": {
"elements": [
"id.contact.individualName",
...
"data-identification": {
"elements": [
"id.dataid.abstract",
"id.dataid.purpose",
"id.dataid.keyword",
...
Translations for the different packages/elements are defined in the translation files: web-ui/src/main/resources/catalog/locales/en-admin.json
"batchreplacer-section-metadata": "Metadata",
"batchreplacer-section-data-identification": "Data Identification",
"batchreplacer-section-service-identification": "Service Identification",
"batchreplacer-section-maintenance-information": "Maintenance Information",
"batchreplacer-section-content-information": "Content Information",
"batchreplacer-section-distribution-information": "Distribution Information",
"batchreplacer-el-id.contact.individualName": "Contact > Individual Name",
"batchreplacer-el-id.contact.organisationName": "Contact > Organization Name",
"batchreplacer-el-id.contact.voicePhone": "Contact > Voice phone",
In the iso19139 schema has been added a xslt massive-content-update.xsl
in the process
folder. This xslt receives an xml content with the list of replacements and applies it to the selected metadata:
List of replacements received by the process, for each replacement are defined these values:
- Field identifier
- Search value
- Replace value
<replacements>
<replacement>
<field>id.contact.individualName</field>
<searchValue>John</searchValue>
<replaceValue>Jennifer</replaceValue>
</replacement>
<replacement>
<field>id.contact.voicePhone</field>
<searchValue>44455454</searchValue>
<replaceValue>35445524</replaceValue>
</replacement>
</replacements>
The process applies the replacements and annotates the xml fields updated so can be displayed in the results report:
<!-- METADATA CONTACT updates: gmd:MD_Metadata/gmd:contact -->
<!-- individualName -->
<xsl:template match="gmd:MD_Metadata/gmd:contact/gmd:CI_ResponsibleParty/gmd:individualName">
<xsl:call-template name="replaceField">
<xsl:with-param name="fieldId">id.contact.individualName</xsl:with-param>
</xsl:call-template>
</xsl:template>
Here is a simplified snippet of the replacement template to highlight the checks done to apply a replacement and the annotation of a change in the field content:
<xsl:template name="replaceField">
<xsl:param name="fieldId" />
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:choose>
<!-- If there's a replacement for this field applied -->
<xsl:when test="$replacements/replacements/replacement[field = $fieldId] and string($replacements/replacements/replacement[field = $fieldId]/searchValue)">
<xsl:variable name="currentVal" select="gco:CharacterString" />
<xsl:variable name="newVal" select="replace(gco:CharacterString, $replacements/replacements/replacement[field = $fieldId]/searchValue, $replacements/replacements/replacement[field = $fieldId]/replaceValue, $case_insensitive)" />
<!-- If the field content has change --> annotate the change --->
<xsl:if test="$currentVal != $newVal">
<xsl:attribute name="geonet:change" select="$fieldId" />
<xsl:attribute name="geonet:original" select="$currentVal" />
<xsl:attribute name="geonet:new" select="$newVal" />
</xsl:if>
<xsl:value-of select="$newVal" />
</xsl:when>
<!-- No replacement for the field, just copy it -->
<xsl:otherwise>
<xsl:apply-templates select="@*|node()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
- Type: Search-UI
- Module: services, web-client, web
- Vote Proposed: 24 april 2014
- +1 from Patrizia, Francois, Jose
- Jose García
- Juan Luis Rodríguez
If you have some comments, start a discussion, raise an issue or use one of our other communication channels to talk to us.