From 5d0352a257d3565d80a3d80f031f071e38b49d6a Mon Sep 17 00:00:00 2001 From: Julian Schneider Date: Fri, 2 Aug 2024 13:50:11 +0200 Subject: [PATCH 1/9] Expose list of export formats in Info API --- src/main/java/edu/harvard/iq/dataverse/api/Info.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/edu/harvard/iq/dataverse/api/Info.java b/src/main/java/edu/harvard/iq/dataverse/api/Info.java index 257519677d3..d81816d2475 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/Info.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/Info.java @@ -12,12 +12,14 @@ import jakarta.ws.rs.Produces; import org.apache.commons.io.IOUtils; +import edu.harvard.iq.dataverse.export.ExportService; import edu.harvard.iq.dataverse.settings.JvmSettings; import edu.harvard.iq.dataverse.settings.SettingsServiceBean; import edu.harvard.iq.dataverse.util.BundleUtil; import edu.harvard.iq.dataverse.util.SystemConfig; import jakarta.ejb.EJB; import jakarta.json.Json; +import jakarta.json.JsonArrayBuilder; import jakarta.json.JsonValue; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; @@ -92,6 +94,14 @@ public Response getZipDownloadLimit() { return ok(zipDownloadLimit); } + @GET + @Path("exportFormats") + public Response getExportFormats() { + JsonArrayBuilder responseModel = Json.createArrayBuilder(); + ExportService.getInstance().getExportersLabels().forEach(labels -> responseModel.add(Json.createObjectBuilder().add("displayName", labels[0]).add("formatName", labels[1]))); + return ok(responseModel); + } + private Response getSettingResponseByKey(SettingsServiceBean.Key key) { String setting = settingsService.getValueForKey(key); if (setting != null) { From 49dd83b5220895225cc039ea82baabcefd71387b Mon Sep 17 00:00:00 2001 From: Julian Schneider Date: Fri, 2 Aug 2024 14:41:07 +0200 Subject: [PATCH 2/9] Document exportFormats method in native API guide --- doc/sphinx-guides/source/api/native-api.rst | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/doc/sphinx-guides/source/api/native-api.rst b/doc/sphinx-guides/source/api/native-api.rst index e7ed71f06ef..21346956839 100644 --- a/doc/sphinx-guides/source/api/native-api.rst +++ b/doc/sphinx-guides/source/api/native-api.rst @@ -4618,6 +4618,25 @@ The fully expanded example above (without environment variables) looks like this curl "https://demo.dataverse.org/api/info/settings/:MaxEmbargoDurationInMonths" +Get Export Formats +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Get the available export formats. The response contains a list of objects each containing the display name and format name for an available exporter. + +.. note:: See :ref:`curl-examples-and-environment-variables` if you are unfamiliar with the use of export below. + +.. code-block:: bash + + export SERVER_URL=https://demo.dataverse.org + + curl "$SERVER_URL/api/info/exportFormats" + +The fully expanded example above (without environment variables) looks like this: + +.. code-block:: bash + + curl "https://demo.dataverse.org/api/info/exportFormats" + .. _metadata-blocks-api: Metadata Blocks From cc99729e6480193468e7308fe52a478ec5edb8ec Mon Sep 17 00:00:00 2001 From: Julian Schneider Date: Wed, 28 Aug 2024 10:47:31 +0200 Subject: [PATCH 3/9] Update api/info/exportFormats to give more available info, restructuring response as JSON object --- .../edu/harvard/iq/dataverse/api/Info.java | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/api/Info.java b/src/main/java/edu/harvard/iq/dataverse/api/Info.java index d81816d2475..2439c996816 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/Info.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/Info.java @@ -17,9 +17,12 @@ import edu.harvard.iq.dataverse.settings.SettingsServiceBean; import edu.harvard.iq.dataverse.util.BundleUtil; import edu.harvard.iq.dataverse.util.SystemConfig; +import io.gdcc.spi.export.Exporter; +import io.gdcc.spi.export.ExportException; +import io.gdcc.spi.export.XMLExporter; import jakarta.ejb.EJB; import jakarta.json.Json; -import jakarta.json.JsonArrayBuilder; +import jakarta.json.JsonObjectBuilder; import jakarta.json.JsonValue; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; @@ -97,8 +100,26 @@ public Response getZipDownloadLimit() { @GET @Path("exportFormats") public Response getExportFormats() { - JsonArrayBuilder responseModel = Json.createArrayBuilder(); - ExportService.getInstance().getExportersLabels().forEach(labels -> responseModel.add(Json.createObjectBuilder().add("displayName", labels[0]).add("formatName", labels[1]))); + JsonObjectBuilder responseModel = Json.createObjectBuilder(); + ExportService instance = ExportService.getInstance(); + for (String[] labels : instance.getExportersLabels()) { + try { + Exporter exporter = instance.getExporter(labels[1]); + JsonObjectBuilder exporterObject = Json.createObjectBuilder().add("displayName", labels[0]) + .add("mediaType", exporter.getMediaType()).add("isHarvestable", exporter.isHarvestable()) + .add("isVisibleInUserInterface", exporter.isAvailableToUsers()); + if (exporter instanceof XMLExporter xmlExporter) { + exporterObject.add("XMLNameSpace", xmlExporter.getXMLNameSpace()) + .add("XMLSchemaLocation", xmlExporter.getXMLSchemaLocation()) + .add("XMLSchemaVersion", xmlExporter.getXMLSchemaVersion()); + } + responseModel.add(labels[1], exporterObject); + } + catch (ExportException ex){ + logger.warning("Failed to get: " + labels[1]); + logger.warning(ex.getLocalizedMessage()); + } + } return ok(responseModel); } From 3b2c8e5aeda5e401e60586b239bae7e5285f36fd Mon Sep 17 00:00:00 2001 From: Julian Schneider Date: Wed, 28 Aug 2024 11:07:26 +0200 Subject: [PATCH 4/9] Document updated exportFormats method in native API guide --- doc/sphinx-guides/source/api/native-api.rst | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/doc/sphinx-guides/source/api/native-api.rst b/doc/sphinx-guides/source/api/native-api.rst index 21346956839..190bc634237 100644 --- a/doc/sphinx-guides/source/api/native-api.rst +++ b/doc/sphinx-guides/source/api/native-api.rst @@ -4621,7 +4621,17 @@ The fully expanded example above (without environment variables) looks like this Get Export Formats ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Get the available export formats. The response contains a list of objects each containing the display name and format name for an available exporter. +Get the available export formats, including custom formats. + +The response contains an object with available format names as keys, and as values an object with the following properties: + +* ``displayName`` +* ``mediaType`` +* ``isHarvestable`` +* ``isVisibleInUserInterface`` (corresponds to isAvailableToUsers) +* ``XMLNameSpace`` (only for XML exporters) +* ``XMLSchemaLocation`` (only for XML exporters) +* ``XMLSchemaVersion`` (only for XML exporters) .. note:: See :ref:`curl-examples-and-environment-variables` if you are unfamiliar with the use of export below. From 95d34c8704367dd982906934f812b28d327874b4 Mon Sep 17 00:00:00 2001 From: Julian Schneider Date: Wed, 28 Aug 2024 14:08:33 +0200 Subject: [PATCH 5/9] Add API test for api/info/exportFormats --- .../edu/harvard/iq/dataverse/api/InfoIT.java | 16 ++++++++++++++++ src/test/resources/json/export-formats.json | 1 + 2 files changed, 17 insertions(+) create mode 100644 src/test/resources/json/export-formats.json diff --git a/src/test/java/edu/harvard/iq/dataverse/api/InfoIT.java b/src/test/java/edu/harvard/iq/dataverse/api/InfoIT.java index 5e436dd0e98..286f9789ed6 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/InfoIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/InfoIT.java @@ -3,7 +3,10 @@ import static io.restassured.RestAssured.given; import io.restassured.response.Response; import edu.harvard.iq.dataverse.settings.SettingsServiceBean; +import com.google.gson.Gson; +import com.google.gson.JsonObject; import org.junit.jupiter.api.AfterAll; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import static jakarta.ws.rs.core.Response.Status.BAD_REQUEST; @@ -81,6 +84,19 @@ public void testGetZipDownloadLimit() { .body("data", notNullValue()); } + @Test + public void testGetExportFormats() { + Response response = given().urlEncodingEnabled(false) + .get("/api/info/exportFormats"); + response.prettyPrint(); + response.then().assertThat().statusCode(OK.getStatusCode()); + + String expectedJson = UtilIT.getDatasetJson("src/test/resources/json/export-formats.json"); + JsonObject expectedJsonObject = new Gson().fromJson(expectedJson, JsonObject.class); + JsonObject actualJsonObject = new Gson().fromJson(response.getBody().asString(), JsonObject.class); + assertEquals(expectedJsonObject, actualJsonObject.get("data")); + } + private void testSettingEndpoint(SettingsServiceBean.Key settingKey, String testSettingValue) { String endpoint = "/api/info/settings/" + settingKey; diff --git a/src/test/resources/json/export-formats.json b/src/test/resources/json/export-formats.json new file mode 100644 index 00000000000..9cf1984eb6a --- /dev/null +++ b/src/test/resources/json/export-formats.json @@ -0,0 +1 @@ +{"OAI_ORE":{"displayName":"OAI_ORE","mediaType":"application/json","isHarvestable":false,"isVisibleInUserInterface":true},"Datacite":{"displayName":"DataCite","mediaType":"application/xml","isHarvestable":true,"isVisibleInUserInterface":true,"XMLNameSpace":"http://datacite.org/schema/kernel-3","XMLSchemaLocation":"http://datacite.org/schema/kernel-3 http://schema.datacite.org/meta/kernel-3/metadata.xsd","XMLSchemaVersion":"3.0"},"oai_dc":{"displayName":"Dublin Core","mediaType":"application/xml","isHarvestable":true,"isVisibleInUserInterface":false,"XMLNameSpace":"http://www.openarchives.org/OAI/2.0/oai_dc/","XMLSchemaLocation":"http://www.openarchives.org/OAI/2.0/oai_dc.xsd","XMLSchemaVersion":"2.0"},"oai_datacite":{"displayName":"OpenAIRE","mediaType":"application/xml","isHarvestable":true,"isVisibleInUserInterface":true,"XMLNameSpace":"http://datacite.org/schema/kernel-4","XMLSchemaLocation":"http://schema.datacite.org/meta/kernel-4.1/metadata.xsd","XMLSchemaVersion":"4.1"},"schema.org":{"displayName":"Schema.org JSON-LD","mediaType":"application/json","isHarvestable":false,"isVisibleInUserInterface":true},"ddi":{"displayName":"DDI","mediaType":"application/xml","isHarvestable":false,"isVisibleInUserInterface":true,"XMLNameSpace":"ddi:codebook:2_5","XMLSchemaLocation":"https://ddialliance.org/Specification/DDI-Codebook/2.5/XMLSchema/codebook.xsd","XMLSchemaVersion":"2.5"},"dcterms":{"displayName":"Dublin Core","mediaType":"application/xml","isHarvestable":false,"isVisibleInUserInterface":true,"XMLNameSpace":"http://purl.org/dc/terms/","XMLSchemaLocation":"http://dublincore.org/schemas/xmls/qdc/dcterms.xsd","XMLSchemaVersion":"2.0"},"html":{"displayName":"DDI HTML Codebook","mediaType":"text/html","isHarvestable":false,"isVisibleInUserInterface":true},"dataverse_json":{"displayName":"JSON","mediaType":"application/json","isHarvestable":true,"isVisibleInUserInterface":true},"oai_ddi":{"displayName":"DDI","mediaType":"application/xml","isHarvestable":true,"isVisibleInUserInterface":false,"XMLNameSpace":"ddi:codebook:2_5","XMLSchemaLocation":"https://ddialliance.org/Specification/DDI-Codebook/2.5/XMLSchema/codebook.xsd","XMLSchemaVersion":"2.5"}} \ No newline at end of file From 3f81981287643f2ac7d37bce8f29bc86f9088ca6 Mon Sep 17 00:00:00 2001 From: Julian Schneider Date: Wed, 28 Aug 2024 14:31:53 +0200 Subject: [PATCH 6/9] Add release note snippet for exportFormats API method release --- doc/release-notes/expose-export-formats.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 doc/release-notes/expose-export-formats.md diff --git a/doc/release-notes/expose-export-formats.md b/doc/release-notes/expose-export-formats.md new file mode 100644 index 00000000000..7e685b426fa --- /dev/null +++ b/doc/release-notes/expose-export-formats.md @@ -0,0 +1,2 @@ +# New API method for listing the available exporters +Found at `/api/info/exportFormats`, produces an object with available format names as keys, and as values an object with various info about the exporter. \ No newline at end of file From 594acb7c0cdaa3815f0fc3861d97022e0df5a66e Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Tue, 12 Nov 2024 14:29:58 -0500 Subject: [PATCH 7/9] remove Gson and test based on content, not string match #10739 --- .../edu/harvard/iq/dataverse/api/InfoIT.java | 21 +++-- src/test/resources/json/export-formats.json | 84 ++++++++++++++++++- 2 files changed, 95 insertions(+), 10 deletions(-) diff --git a/src/test/java/edu/harvard/iq/dataverse/api/InfoIT.java b/src/test/java/edu/harvard/iq/dataverse/api/InfoIT.java index 286f9789ed6..b198d2769a0 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/InfoIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/InfoIT.java @@ -3,17 +3,17 @@ import static io.restassured.RestAssured.given; import io.restassured.response.Response; import edu.harvard.iq.dataverse.settings.SettingsServiceBean; -import com.google.gson.Gson; -import com.google.gson.JsonObject; import org.junit.jupiter.api.AfterAll; -import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import static jakarta.ws.rs.core.Response.Status.BAD_REQUEST; import static jakarta.ws.rs.core.Response.Status.NOT_FOUND; import static jakarta.ws.rs.core.Response.Status.OK; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Paths; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.notNullValue; +import org.skyscreamer.jsonassert.JSONAssert; public class InfoIT { @@ -85,16 +85,19 @@ public void testGetZipDownloadLimit() { } @Test - public void testGetExportFormats() { + public void testGetExportFormats() throws IOException { Response response = given().urlEncodingEnabled(false) .get("/api/info/exportFormats"); response.prettyPrint(); response.then().assertThat().statusCode(OK.getStatusCode()); - String expectedJson = UtilIT.getDatasetJson("src/test/resources/json/export-formats.json"); - JsonObject expectedJsonObject = new Gson().fromJson(expectedJson, JsonObject.class); - JsonObject actualJsonObject = new Gson().fromJson(response.getBody().asString(), JsonObject.class); - assertEquals(expectedJsonObject, actualJsonObject.get("data")); + String actual = response.getBody().asString(); + String expected = + java.nio.file.Files.readString( + Paths.get("src/test/resources/json/export-formats.json"), + StandardCharsets.UTF_8); + JSONAssert.assertEquals(expected, actual, true); + } diff --git a/src/test/resources/json/export-formats.json b/src/test/resources/json/export-formats.json index 9cf1984eb6a..0bca2314a8e 100644 --- a/src/test/resources/json/export-formats.json +++ b/src/test/resources/json/export-formats.json @@ -1 +1,83 @@ -{"OAI_ORE":{"displayName":"OAI_ORE","mediaType":"application/json","isHarvestable":false,"isVisibleInUserInterface":true},"Datacite":{"displayName":"DataCite","mediaType":"application/xml","isHarvestable":true,"isVisibleInUserInterface":true,"XMLNameSpace":"http://datacite.org/schema/kernel-3","XMLSchemaLocation":"http://datacite.org/schema/kernel-3 http://schema.datacite.org/meta/kernel-3/metadata.xsd","XMLSchemaVersion":"3.0"},"oai_dc":{"displayName":"Dublin Core","mediaType":"application/xml","isHarvestable":true,"isVisibleInUserInterface":false,"XMLNameSpace":"http://www.openarchives.org/OAI/2.0/oai_dc/","XMLSchemaLocation":"http://www.openarchives.org/OAI/2.0/oai_dc.xsd","XMLSchemaVersion":"2.0"},"oai_datacite":{"displayName":"OpenAIRE","mediaType":"application/xml","isHarvestable":true,"isVisibleInUserInterface":true,"XMLNameSpace":"http://datacite.org/schema/kernel-4","XMLSchemaLocation":"http://schema.datacite.org/meta/kernel-4.1/metadata.xsd","XMLSchemaVersion":"4.1"},"schema.org":{"displayName":"Schema.org JSON-LD","mediaType":"application/json","isHarvestable":false,"isVisibleInUserInterface":true},"ddi":{"displayName":"DDI","mediaType":"application/xml","isHarvestable":false,"isVisibleInUserInterface":true,"XMLNameSpace":"ddi:codebook:2_5","XMLSchemaLocation":"https://ddialliance.org/Specification/DDI-Codebook/2.5/XMLSchema/codebook.xsd","XMLSchemaVersion":"2.5"},"dcterms":{"displayName":"Dublin Core","mediaType":"application/xml","isHarvestable":false,"isVisibleInUserInterface":true,"XMLNameSpace":"http://purl.org/dc/terms/","XMLSchemaLocation":"http://dublincore.org/schemas/xmls/qdc/dcterms.xsd","XMLSchemaVersion":"2.0"},"html":{"displayName":"DDI HTML Codebook","mediaType":"text/html","isHarvestable":false,"isVisibleInUserInterface":true},"dataverse_json":{"displayName":"JSON","mediaType":"application/json","isHarvestable":true,"isVisibleInUserInterface":true},"oai_ddi":{"displayName":"DDI","mediaType":"application/xml","isHarvestable":true,"isVisibleInUserInterface":false,"XMLNameSpace":"ddi:codebook:2_5","XMLSchemaLocation":"https://ddialliance.org/Specification/DDI-Codebook/2.5/XMLSchema/codebook.xsd","XMLSchemaVersion":"2.5"}} \ No newline at end of file +{ + "status": "OK", + "data": { + "OAI_ORE": { + "displayName": "OAI_ORE", + "mediaType": "application/json", + "isHarvestable": false, + "isVisibleInUserInterface": true + }, + "Datacite": { + "displayName": "DataCite", + "mediaType": "application/xml", + "isHarvestable": true, + "isVisibleInUserInterface": true, + "XMLNameSpace": "http://datacite.org/schema/kernel-3", + "XMLSchemaLocation": "http://datacite.org/schema/kernel-3 http://schema.datacite.org/meta/kernel-3/metadata.xsd", + "XMLSchemaVersion": "3.0" + }, + "oai_dc": { + "displayName": "Dublin Core", + "mediaType": "application/xml", + "isHarvestable": true, + "isVisibleInUserInterface": false, + "XMLNameSpace": "http://www.openarchives.org/OAI/2.0/oai_dc/", + "XMLSchemaLocation": "http://www.openarchives.org/OAI/2.0/oai_dc.xsd", + "XMLSchemaVersion": "2.0" + }, + "oai_datacite": { + "displayName": "OpenAIRE", + "mediaType": "application/xml", + "isHarvestable": true, + "isVisibleInUserInterface": true, + "XMLNameSpace": "http://datacite.org/schema/kernel-4", + "XMLSchemaLocation": "http://schema.datacite.org/meta/kernel-4.1/metadata.xsd", + "XMLSchemaVersion": "4.1" + }, + "schema.org": { + "displayName": "Schema.org JSON-LD", + "mediaType": "application/json", + "isHarvestable": false, + "isVisibleInUserInterface": true + }, + "ddi": { + "displayName": "DDI", + "mediaType": "application/xml", + "isHarvestable": false, + "isVisibleInUserInterface": true, + "XMLNameSpace": "ddi:codebook:2_5", + "XMLSchemaLocation": "https://ddialliance.org/Specification/DDI-Codebook/2.5/XMLSchema/codebook.xsd", + "XMLSchemaVersion": "2.5" + }, + "dcterms": { + "displayName": "Dublin Core", + "mediaType": "application/xml", + "isHarvestable": false, + "isVisibleInUserInterface": true, + "XMLNameSpace": "http://purl.org/dc/terms/", + "XMLSchemaLocation": "http://dublincore.org/schemas/xmls/qdc/dcterms.xsd", + "XMLSchemaVersion": "2.0" + }, + "html": { + "displayName": "DDI HTML Codebook", + "mediaType": "text/html", + "isHarvestable": false, + "isVisibleInUserInterface": true + }, + "dataverse_json": { + "displayName": "JSON", + "mediaType": "application/json", + "isHarvestable": true, + "isVisibleInUserInterface": true + }, + "oai_ddi": { + "displayName": "DDI", + "mediaType": "application/xml", + "isHarvestable": true, + "isVisibleInUserInterface": false, + "XMLNameSpace": "ddi:codebook:2_5", + "XMLSchemaLocation": "https://ddialliance.org/Specification/DDI-Codebook/2.5/XMLSchema/codebook.xsd", + "XMLSchemaVersion": "2.5" + } + } +} From 48d04e89de2f41de2b1941fb42a7c893ad22c701 Mon Sep 17 00:00:00 2001 From: julian-schneider <130765495+julian-schneider@users.noreply.github.com> Date: Wed, 20 Nov 2024 12:48:19 +0100 Subject: [PATCH 8/9] Add PR number to doc/release-notes/expose-export-formats.md Co-authored-by: Philip Durbin --- doc/release-notes/expose-export-formats.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/release-notes/expose-export-formats.md b/doc/release-notes/expose-export-formats.md index 7e685b426fa..a21906d7bbb 100644 --- a/doc/release-notes/expose-export-formats.md +++ b/doc/release-notes/expose-export-formats.md @@ -1,2 +1,2 @@ # New API method for listing the available exporters -Found at `/api/info/exportFormats`, produces an object with available format names as keys, and as values an object with various info about the exporter. \ No newline at end of file +Found at `/api/info/exportFormats`, produces an object with available format names as keys, and as values an object with various info about the exporter. See also #10739. \ No newline at end of file From f3b72c66fc89f8ec5fa7eb1f48fe187eabe7c8bf Mon Sep 17 00:00:00 2001 From: Julian Schneider Date: Wed, 20 Nov 2024 15:56:19 +0100 Subject: [PATCH 9/9] Update expected JSON for api/info/exportFormats IT Test --- src/test/resources/json/export-formats.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/test/resources/json/export-formats.json b/src/test/resources/json/export-formats.json index 0bca2314a8e..b4dc0168629 100644 --- a/src/test/resources/json/export-formats.json +++ b/src/test/resources/json/export-formats.json @@ -12,9 +12,9 @@ "mediaType": "application/xml", "isHarvestable": true, "isVisibleInUserInterface": true, - "XMLNameSpace": "http://datacite.org/schema/kernel-3", - "XMLSchemaLocation": "http://datacite.org/schema/kernel-3 http://schema.datacite.org/meta/kernel-3/metadata.xsd", - "XMLSchemaVersion": "3.0" + "XMLNameSpace": "http://datacite.org/schema/kernel-4", + "XMLSchemaLocation": "http://datacite.org/schema/kernel-4 http://schema.datacite.org/meta/kernel-4.5/metadata.xsd", + "XMLSchemaVersion": "4.5" }, "oai_dc": { "displayName": "Dublin Core", @@ -41,7 +41,7 @@ "isVisibleInUserInterface": true }, "ddi": { - "displayName": "DDI", + "displayName": "DDI Codebook v2", "mediaType": "application/xml", "isHarvestable": false, "isVisibleInUserInterface": true, @@ -71,7 +71,7 @@ "isVisibleInUserInterface": true }, "oai_ddi": { - "displayName": "DDI", + "displayName": "DDI Codebook v2", "mediaType": "application/xml", "isHarvestable": true, "isVisibleInUserInterface": false,