Add validation for XML namespaces in v3 and v4 guidelines.

This commit is contained in:
Lampros Smyrnaios 2023-07-27 14:41:00 +03:00
parent 8b4da5c4eb
commit 7be1dbe493
6 changed files with 97 additions and 96 deletions

View File

@ -69,7 +69,7 @@ class ElementSpecCompiler {
// TODO: Should we escape the arg?
private static String xpathForNodeName(String name) {
return "local-name()='" + name + "'";
return "name()='" + name + "'";
}
private static String xpathForNodeName(String name, String valuePrefix) {

View File

@ -63,7 +63,7 @@ public abstract class AbstractOpenAireProfile implements XMLApplicationProfile {
return XMLCardinalityRule
.builder()
.setId(ElementSpec.APPLICABILITY_RULE_ID)
.setXPathExpression("//*[local-name()='" + elementName + "']")
.setXPathExpression("//*[name()='" + elementName + "']")
.setIsInclusive(true).setRange(1, Long.MAX_VALUE)
.build();
}

View File

@ -77,69 +77,69 @@ public final class LiteratureGuidelinesV3Profile extends AbstractOpenAireProfile
};
private static final ElementSpec TITLE_SPEC = Builders
.forMandatoryElement("title", ONE_TO_N)
.forMandatoryElement("dc:title", ONE_TO_N)
.build();
private static final ElementSpec CREATOR_SPEC = Builders
.forMandatoryElement("creator", ONE_TO_N)
.forMandatoryElement("dc:creator", ONE_TO_N)
.build();
private static final ElementSpec PROJECT_IDENTIFIER_SPEC = Builders
.forMandatoryIfApplicableElement("relation", ONE, elementIsPresent("relation"))
.forMandatoryIfApplicableElement("dc:relation", ONE, elementIsPresent("dc:relation"))
.allowedValues(new RegexValuePredicate(COMPILED_PROJECT_IDENTIFIER_REGEX))
.build();
private static final ElementSpec ACCESS_LEVEL_SPEC = Builders
.forMandatoryElement("rights", ONE).allowedValues(repoAccessTerms)
.forMandatoryElement("dc:rights", ONE).allowedValues(repoAccessTerms)
.build();
private static final ElementSpec LICENSE_CONDITION_SPEC = Builders
.forRecommendedRepeatableElement("rights")
.forRecommendedRepeatableElement("dc:rights")
.allowedValues(new RegexValuePredicate(COMPILED_LICENSE_CONDITION_REG_EX))
.build();
private static final ElementSpec EMBARGO_END_DATE_SPEC = Builders
.forMandatoryIfApplicableElement("date", ONE, applicabilityRuleForEmbargoEndDate())
.forMandatoryIfApplicableElement("dc:date", ONE, applicabilityRuleForEmbargoEndDate())
.allowedValues(new EmbargoedEndDateValuePredicate())
.build();
private static final ElementSpec ALT_IDENTIFIER_SPEC = Builders
.forRecommendedRepeatableElement("relation")
.forRecommendedRepeatableElement("dc:relation")
.allowedValues(new RegexValuePredicate(COMPILED_ALT_IDENTIFIER_REG_EX))
.build();
private static final ElementSpec PUBLICATION_REF_SPEC = Builders
.forRecommendedRepeatableElement("relation")
.forRecommendedRepeatableElement("dc:relation")
.allowedValues(new RegexValuePredicate(COMPILED_PUBLICATION_REFERENCE_REG_EX))
.build();
private static final ElementSpec DATASET_REF_SPEC = Builders
.forRecommendedRepeatableElement("relation")
.forRecommendedRepeatableElement("dc:relation")
.allowedValues(new RegexValuePredicate(COMPILED_DATASET_REFERENCE_REG_EX))
.build();
//TODO value is either a keyword (free text) or a classification (info:eu-repo/classification)
// v3 guideliness recommends ddc classification (Dewey Decimal Classification)
private static final ElementSpec SUBJECT_SPEC = Builders
.forMandatoryIfApplicableElement("subject", ONE_TO_N, elementIsPresent("subject"))
.forMandatoryIfApplicableElement("dc:subject", ONE_TO_N, elementIsPresent("dc:subject"))
.build();
private static final ElementSpec DESCRIPTION_SPEC = Builders
.forMandatoryIfApplicableElement("description", ONE_TO_N, elementIsPresent("description"))
.forMandatoryIfApplicableElement("dc:description", ONE_TO_N, elementIsPresent("dc:description"))
.build();
private static final ElementSpec PUBLISHER_SPEC = Builders
.forMandatoryIfApplicableElement("publisher", ONE_TO_N, elementIsPresent("publisher"))
.forMandatoryIfApplicableElement("dc:publisher", ONE_TO_N, elementIsPresent("dc:publisher"))
.build();
private static final ElementSpec CONTRIBUTOR_SPEC = Builders
.forRecommendedRepeatableElement("contributor")
.forRecommendedRepeatableElement("dc:contributor")
.build();
//TODO
// Search element -> dc:date AND NOT embargoedDate
private static final ElementSpec PUBLICATION_DATE_SPEC = Builders
.forMandatoryElement("date", ONE)
.forMandatoryElement("dc:date", ONE)
.allowedValues(new RegexValuePredicate(COMPILED_PUBLICATION_DATE_REG_EX))
.build();
@ -147,7 +147,7 @@ public final class LiteratureGuidelinesV3Profile extends AbstractOpenAireProfile
// Search element -> dc:type AND values IN publicationTypes set
//TODO: Check it is first occurrence
private static final ElementSpec PUBLICATION_TYPE_M_SPEC = Builders
.forMandatoryElement("type", ONE)
.forMandatoryElement("dc:type", ONE)
.atPosition(ElementPosition.FIRST)
.allowedValues(publicationTypes)
.build();
@ -156,47 +156,47 @@ public final class LiteratureGuidelinesV3Profile extends AbstractOpenAireProfile
// Search element -> dc:type AND values NOT IN publicationTypes
//TODO: check it is second occurrence
private static final ElementSpec PUBLICATION_TYPE_O_SPEC = Builders
.forOptionalElement("type")
.forOptionalElement("dc:type")
.atPosition(ElementPosition.SECOND)
.allowedValues(new Predicates.SetOfCaseInsensitiveAllowedValues(publicationTypesAndVersions).negate())
.build();
private static final ElementSpec PUBLICATION_VERSION_SPEC = Builders
.forRecommendedElement("type")
.forRecommendedElement("dc:type")
.allowedValues(publicationVersions)
.build();
private static final ElementSpec FORMAT_SPEC = Builders
.forRecommendedRepeatableElement("format")
.forRecommendedRepeatableElement("dc:format")
.allowedValues(new MediaTypesValuePredicate())
.build();
private static final ElementSpec RESOURCE_IDENTIFIER_SPEC = Builders
.forMandatoryElement("identifier", ONE_TO_N)
.forMandatoryElement("dc:identifier", ONE_TO_N)
.build();
private static final ElementSpec SOURCE_SPEC = Builders
.forRecommendedRepeatableElement("source")
.forRecommendedRepeatableElement("dc:source")
.build();
//TODO values from ISO 639-1 or 639-2 or 639-3 (recommended)
private static final ElementSpec LANGUAGE_SPEC = Builders
.forRecommendedRepeatableElement("language")
.forRecommendedRepeatableElement("dc:language")
.allowedValues(new ISO639ValuePredicate())
.build();
//TODO: Should exclude other dc:relation elements e.g. !containsAllowedValuesOF -> Project Identifier (MA), Alternative Identifier (R), Publication Reference (R), Dataset Reference (R)
private static final ElementSpec RELATION_SPEC = Builders
.forOptionalRepeatableElement("relation")
.forOptionalRepeatableElement("dc:relation")
.allowedValues(relationSpecAllowedValuesPredicate())
.build();
private static final ElementSpec COVERAGE_SPEC = Builders
.forRecommendedRepeatableElement("coverage")
.forRecommendedRepeatableElement("dc:coverage")
.build();
private static final ElementSpec AUDIENCE_SPEC = Builders
.forRecommendedRepeatableElement("audience")
.forRecommendedRepeatableElement("dc:audience")
.allowedValues(audiences)
.build();
@ -204,7 +204,7 @@ public final class LiteratureGuidelinesV3Profile extends AbstractOpenAireProfile
return XMLCardinalityRule.builder().
setId(ElementSpec.APPLICABILITY_RULE_ID).
// first predicate count(...) makes sure there is only one Access Level set and then the second predicate verifies its value.
setXPathExpression("//*[count(//*[local-name()='rights' and starts-with(normalize-space(text()), 'info:eu-repo/semantics/')])=1][local-name()='rights' and normalize-space(text())='info:eu-repo/semantics/embargoedAccess']").
setXPathExpression("//*[count(//*[name()='dc:rights' and starts-with(normalize-space(text()), 'info:eu-repo/semantics/')])=1][name()='dc:rights' and normalize-space(text())='info:eu-repo/semantics/embargoedAccess']").
setRange(1,1).
setIsInclusive(true).
build();

View File

@ -137,61 +137,61 @@ public final class LiteratureGuidelinesV4Profile extends AbstractOpenAireProfile
};
private static final ElementSpec TITLE_SPEC = Builders.
forMandatoryElement("title", ONE_TO_N).
forMandatoryElement("datacite:title", ONE_TO_N).
withOptionalAttribute("xml:lang", new RegexValuePredicate(COMPILED_BCP47_LANG_TAGS_REG_EX)).
withOptionalAttribute("titleType", TITLE_TYPES).
build();
private static final ElementSpec CREATOR_SPEC = Builders.
forMandatoryElement("creator", ONE_TO_N).
forMandatoryElement("datacite:creator", ONE_TO_N).
withSubElement(Builders.
forMandatoryElement("creatorName", ONE).
forMandatoryElement("datacite:creatorName", ONE).
withRecommendedAttribute("nameType", NAME_TYPES)).
withSubElement(Builders.
forRecommendedElement("givenName")).
forRecommendedElement("datacite:givenName")).
withSubElement(Builders.
forRecommendedElement("familyName")).
forRecommendedElement("datacite:familyName")).
withSubElement(Builders.
forRecommendedRepeatableElement("nameIdentifier").
forRecommendedRepeatableElement("datacite:nameIdentifier").
withMandatoryAttribute("nameIdentifierScheme").
withRecommendedAttribute("schemeURI")).
withSubElement(Builders.
forRecommendedRepeatableElement("affiliation")).
forRecommendedRepeatableElement("datacite:affiliation")).
build();
private static final ElementSpec CONTRIBUTOR_SPEC = Builders.
forMandatoryIfApplicableElement("contributor", ONE_TO_N, elementIsPresent("contributor")).
forMandatoryIfApplicableElement("datacite:contributor", ONE_TO_N, elementIsPresent("datacite:contributor")).
withMandatoryAttribute("contributorType", CONTRIBUTOR_TYPES).
withSubElement(Builders.
forMandatoryElement("contributorName", ONE).
forMandatoryElement("datacite:contributorName", ONE).
withRecommendedAttribute("nameType", NAME_TYPES)).
withSubElement(Builders.
forOptionalElement("familyName")).
forOptionalElement("datacite:familyName")).
withSubElement(Builders.
forOptionalElement("givenName")).
forOptionalElement("datacite:givenName")).
withSubElement(Builders.
forRecommendedRepeatableElement("nameIdentifier").
forRecommendedRepeatableElement("datacite:nameIdentifier").
withMandatoryAttribute("nameIdentifierScheme").
withRecommendedAttribute("schemeURI")).
withSubElement(Builders.
forRecommendedRepeatableElement("affiliation")).
forRecommendedRepeatableElement("datacite:affiliation")).
build();
//This property has some issues/annotations in documentation
private static final ElementSpec FUNDING_REFERENCE_SPEC = Builders.
forMandatoryIfApplicableElement("fundingReference", ONE_TO_N, elementIsPresent("fundingReference")).
forMandatoryIfApplicableElement("oaire:fundingReference", ONE_TO_N, elementIsPresent("oaire:fundingReference")).
withSubElement(Builders.
forMandatoryElement("funderName", ONE)).
forMandatoryElement("oaire:funderName", ONE)).
withSubElement(Builders.
forRecommendedElement("funderIdentifier").
forRecommendedElement("oaire:funderIdentifier").
withRecommendedAttribute("funderIdentifierType", FUNDER_IDENTIFIER_TYPES)).
withSubElement(Builders.
forOptionalElement("fundingStream")).
forOptionalElement("oaire:fundingStream")).
withSubElement(Builders.
forMandatoryIfApplicableElement("awardNumber", ONE, elementIsPresent("awardNumber")).
forMandatoryIfApplicableElement("oaire:awardNumber", ONE, elementIsPresent("oaire:awardNumber")).
withRecommendedAttribute("awardURI")).
withSubElement(Builders.
forRecommendedElement("awardTitle")).
forRecommendedElement("oaire:awardTitle")).
build();
//TODO: Allowed values are referred as "suggested" in the documentation, but then a controlled list is given.
@ -199,12 +199,12 @@ public final class LiteratureGuidelinesV4Profile extends AbstractOpenAireProfile
// https://bitbucket.org/saikos/openaire-validator/issues/40
// https://bitbucket.org/saikos/openaire-validator/issues/32/
private static final ElementSpec ALTERNATE_IDENTIFIER_SPEC = Builders.
forRecommendedRepeatableElement("alternateIdentifier").
forRecommendedRepeatableElement("datacite:alternateIdentifier").
withMandatoryAttribute("alternateIdentifierType", IDENTIFIER_TYPES).
build();
private static final ElementSpec RELATED_IDENTIFIER_SPEC = Builders.
forRecommendedRepeatableElement("relatedIdentifier").
forRecommendedRepeatableElement("datacite:relatedIdentifier").
withMandatoryAttribute("relatedIdentifierType", IDENTIFIER_TYPES).
withMandatoryAttribute("relationType", RELATION_TYPES).
//TODO: For following 3 attributes. Need a way to target relationType attribute of current element
@ -223,13 +223,13 @@ public final class LiteratureGuidelinesV4Profile extends AbstractOpenAireProfile
//TODO: Implement proper applicability rule
//LEONIDAS: The withMandatoryAttribute fails whe another date element eg. for Publication Date exists
private static final ElementSpec EMBARGO_PERIOD_DATE_SPEC = Builders.
forMandatoryIfApplicableElement("date", ONE_TO_N, applicabilityRuleForEmbargoPeriodDate()).
forMandatoryIfApplicableElement("datacite:date", ONE_TO_N, applicabilityRuleForEmbargoPeriodDate()).
withMandatoryAttribute("dateType", EMBARGO_DATE_TYPES).
allowedValues(new RegexValuePredicate(COMPILED_YYYY_MM_DD_RANGE_REGEX).or(new RegexValuePredicate(COMPILED_YEAR_YYYY_REG_EX))).
build();
// private static final ElementSpec EMBARGO_PERIOD_DATE_SPEC = Builders.
// forMandatoryIfApplicableElement("date", TWO, applicabilityRuleForEmbargoPeriodDate()).
// forMandatoryIfApplicableElement("datacite:date", TWO, applicabilityRuleForEmbargoPeriodDate()).
// withMandatoryAttribute("dateType", EMBARGO_DATE_TYPES).
// build();
@ -237,12 +237,12 @@ public final class LiteratureGuidelinesV4Profile extends AbstractOpenAireProfile
There are no "strict" allowed values. Recommendations are IETF BCP 47 and ISO 639-x
*/
private static final ElementSpec LANGUAGE_SPEC = Builders.
forMandatoryIfApplicableElement("language", ONE_TO_N, elementIsPresent("language")).
forMandatoryIfApplicableElement("dc:language", ONE_TO_N, elementIsPresent("dc:language")).
allowedValues(new RegexValuePredicate(COMPILED_BCP47_LANG_TAGS_REG_EX).or(new ISO639ValuePredicate())).
build();
private static final ElementSpec PUBLISHER_SPEC = Builders.
forMandatoryIfApplicableElement("publisher", ONE_TO_N, elementIsPresent("publisher")).
forMandatoryIfApplicableElement("dc:publisher", ONE_TO_N, elementIsPresent("dc:publisher")).
build();
/*
@ -251,98 +251,98 @@ public final class LiteratureGuidelinesV4Profile extends AbstractOpenAireProfile
"Recommended" best practice for encoding the date value is ISO 8601 [W3CDTF] (YYYY-MM-DD) (YYYY mandatory)
*/
private static final ElementSpec PUBLICATION_DATE_SPEC = Builders.
forMandatoryElement("date", ONE).
forMandatoryElement("datacite:date", ONE).
withMandatoryAttribute("dateType", PUBLICATION_DATE_TYPE).
allowedValues(new RegexValuePredicate(COMPILED_PUBLICATION_DATE_REG_EX).or(new RegexValuePredicate(COMPILED_YYYY_MM_DD_RANGE_REGEX).or(new RegexValuePredicate(COMPILED_YEAR_YYYY_REG_EX)))).
build();
private static final ElementSpec RESOURCE_TYPE_SPEC = Builders.
forMandatoryElement("resourceType", ONE).
forMandatoryElement("oaire:resourceType", ONE).
withMandatoryAttribute("resourceTypeGeneral", RESOURCE_GENERAL_TYPES).
withMandatoryAttribute("uri", RESOURCE_CONCEPT_URIS).
build();
private static final ElementSpec DESCRIPTION_SPEC = Builders.
forMandatoryIfApplicableElement("description", ONE_TO_N, elementIsPresent("description")).
forMandatoryIfApplicableElement("dc:description", ONE_TO_N, elementIsPresent("dc:description")).
withOptionalAttribute("xml:lang", new RegexValuePredicate(COMPILED_BCP47_LANG_TAGS_REG_EX)).
build();
private static final ElementSpec FORMAT_SPEC = Builders.
forRecommendedRepeatableElement("format").
forRecommendedRepeatableElement("dc:format").
allowedValues(new MediaTypesValuePredicate()).
build();
private static final ElementSpec RESOURCE_IDENTIFIER_SPEC = Builders.
forMandatoryElement("identifier", ONE).
forMandatoryElement("datacite:identifier", ONE).
withMandatoryAttribute("identifierType", RESOURCE_IDENTIFIER_TYPES).
build();
private static final ElementSpec ACCESS_RIGHTS_SPEC = Builders.
forMandatoryElement("rights", ONE).
forMandatoryElement("datacite:rights", ONE).
withMandatoryAttribute("uri", ACCESS_RIGHTS_URIS).
allowedValues(ACCESS_RIGHTS_TYPES).
build();
private static final ElementSpec SOURCE_SPEC = Builders.
forRecommendedRepeatableElement("source").
forRecommendedRepeatableElement("dc:source").
build();
//TODO: Should we check URI attribute values are valid?
private static final ElementSpec SUBJECT_SPEC = Builders.
forMandatoryIfApplicableElement("subject", ONE_TO_N, elementIsPresent("subject")).
forMandatoryIfApplicableElement("datacite:subject", ONE_TO_N, elementIsPresent("datacite:subject")).
withOptionalAttribute("subjectScheme").
withOptionalAttribute("schemeURI").
withOptionalAttribute("valueURI").
build();
private static final ElementSpec LICENSE_CONDITION_SPEC = Builders.
forRecommendedElement("licenseCondition").
withMandatoryIfApplicableAttribute("uri", elementIsPresent("licenseCondition")).
withMandatoryIfApplicableAttribute("startDate", elementIsPresent("licenseCondition")).
forRecommendedElement("oaire:licenseCondition").
withMandatoryIfApplicableAttribute("uri", elementIsPresent("oaire:licenseCondition")).
withMandatoryIfApplicableAttribute("startDate", elementIsPresent("oaire:licenseCondition")).
build();
private static final ElementSpec COVERAGE_SPEC = Builders.
forRecommendedRepeatableElement("coverage").
forRecommendedRepeatableElement("dc:coverage").
build();
private static final ElementSpec SIZE_SPEC = Builders.
forOptionalRepeatableElement("size").
forOptionalRepeatableElement("datacite:size").
build();
private static final ElementSpec GEO_LOCATION_SPEC = Builders.
forOptionalRepeatableElement("geoLocation").
forOptionalRepeatableElement("datacite:geoLocation").
withSubElement(Builders.
forOptionalElement("geoLocationPoint").
forOptionalElement("datacite:geoLocationPoint").
withSubElement(Builders.
forMandatoryElement("pointLongitude", ONE)).
forMandatoryElement("datacite:pointLongitude", ONE)).
withSubElement(Builders.
forMandatoryElement("pointLatitude", ONE))).
forMandatoryElement("datacite:pointLatitude", ONE))).
withSubElement(Builders.
forOptionalElement("geoLocationBox").
forOptionalElement("datacite:geoLocationBox").
withSubElement(Builders.
forMandatoryElement("westBoundLongitude", ONE)).
forMandatoryElement("datacite:westBoundLongitude", ONE)).
withSubElement(Builders.
forMandatoryElement("eastBoundLongitude", ONE)).
forMandatoryElement("datacite:eastBoundLongitude", ONE)).
withSubElement(Builders.
forMandatoryElement("southBoundLatitude", ONE)).
forMandatoryElement("datacite:southBoundLatitude", ONE)).
withSubElement(Builders.
forMandatoryElement("northBoundLatitude", ONE))).
forMandatoryElement("datacite:northBoundLatitude", ONE))).
withSubElement(Builders.
forOptionalElement("geoLocationPlace")).
forOptionalElement("datacite:geoLocationPlace")).
withSubElement(Builders.
forOptionalRepeatableElement("geoLocationPolygon").
forOptionalRepeatableElement("datacite:geoLocationPolygon").
withSubElement(Builders.
forMandatoryElement("polygonPoint", FOUR_TO_N).
forMandatoryElement("datacite:polygonPoint", FOUR_TO_N).
withSubElement(Builders.
forMandatoryElement("pointLongitude", ONE)).
forMandatoryElement("datacite:pointLongitude", ONE)).
withSubElement(Builders.
forMandatoryElement("pointLatitude", ONE))).
forMandatoryElement("datacite:pointLatitude", ONE))).
withSubElement(Builders.
forOptionalElement("inPolygonPoint").
forOptionalElement("datacite:inPolygonPoint").
withSubElement(Builders.
forMandatoryElement("pointLongitude", ONE)).
forMandatoryElement("datacite:pointLongitude", ONE)).
withSubElement(Builders.
forMandatoryElement("pointLatitude", ONE)))).
forMandatoryElement("datacite:pointLatitude", ONE)))).
build();
/*
@ -354,57 +354,57 @@ public final class LiteratureGuidelinesV4Profile extends AbstractOpenAireProfile
TODO: Should we cross-check attribute and element value are relevant?
*/
private static final ElementSpec RESOURCE_VERSION_SPEC = Builders.
forRecommendedElement("version").
forRecommendedElement("oaire:version").
withMandatoryIfApplicableAttribute("uri", applicabilityRuleForURIAttributeOfResourceVersion(), RESOURCE_VERSION_URIS).
build();
//TODO: Has annotation/issue: accessRightsURI attribute values also appears on ACCESS_RIGHTS_SPEC. Should check it's the same?
private static final ElementSpec FILE_LOCATION_SPEC = Builders.
forMandatoryIfApplicableElement("file", ONE_TO_N, elementIsPresent("file")).
forMandatoryIfApplicableElement("oaire:file", ONE_TO_N, elementIsPresent("oaire:file")).
withRecommendedAttribute("accessRightsURI", ACCESS_RIGHTS_URIS).
withRecommendedAttribute("mimeType", new MediaTypesValuePredicate()).
withRecommendedAttribute("objectType", FILE_OBJECT_TYPES).
build();
private static final ElementSpec CITATION_TITLE_SPEC = Builders.
forRecommendedElement("citationTitle").
forRecommendedElement("oaire:citationTitle").
build();
private static final ElementSpec CITATION_VOLUME_SPEC = Builders.
forRecommendedElement("citationVolume").
forRecommendedElement("oaire:citationVolume").
build();
private static final ElementSpec CITATION_ISSUE_SPEC = Builders.
forRecommendedElement("citationIssue").
forRecommendedElement("oaire:citationIssue").
build();
private static final ElementSpec CITATION_START_PAGE_SPEC = Builders.
forRecommendedElement("citationStartPage").
forRecommendedElement("oaire:citationStartPage").
build();
private static final ElementSpec CITATION_END_PAGE_SPEC = Builders.
forRecommendedElement("citationEndPage").
forRecommendedElement("oaire:citationEndPage").
build();
private static final ElementSpec CITATION_EDITION_SPEC = Builders.
forRecommendedElement("citationEdition").
forRecommendedElement("oaire:citationEdition").
build();
private static final ElementSpec CITATION_CONFERENCE_PLACE_SPEC = Builders.
forRecommendedElement("citationConferencePlace").
forRecommendedElement("oaire:citationConferencePlace").
build();
//TODO: Implement regex/allowedValuesPredicate
// Date has recommended best practice ISO 8601 [W3CDTF], and two [single date] [start date - end date] formats
private static final ElementSpec CITATION_CONFERENCE_DATE_SPEC = Builders.
forRecommendedElement("citationConferenceDate").
forRecommendedElement("oaire:citationConferenceDate").
allowedValues(new RegexValuePredicate(COMPILED_YYYY_MM_DD_REGEX).or(new RegexValuePredicate(COMPILED_YYYY_MM_DD_RANGE_REGEX))).
build();
//TODO: A non-exhaustive list is provided for values, derived from the Common Education Data Standards vocabulary
// Should we add it?
private static final ElementSpec AUDIENCE_SPEC = Builders.
forOptionalRepeatableElement("audience").
forOptionalRepeatableElement("dcterms:audience").
allowedValues(AUDIENCE_VOCABULARY).
build();

View File

@ -21,7 +21,8 @@ public class Test {
// "src/test/resources/openaireguidelinesV3/dia.library.tuc.gr/Record_21811.xml",
// "src/test/resources/openaireguidelinesV3/cris.vtt.fi/01.xml",
// "src/test/resources/openaireguidelinesV3/cris.vtt.fi/02.xml",
"src/test/resources/openaireguidelinesV3/cris.vtt.fi/03.xml"
// "src/test/resources/openaireguidelinesV3/cris.vtt.fi/03.xml"
"src/test/resources/openaireguidelinesV3/ngi.brage.unit.no/ListRecords_prefix_oai_dc_set_openaire.xml"
};
public static void main(String[] args) {

View File

@ -20,8 +20,8 @@ public class Test_v4 {
private static final String[] FILES = new String[] {
"src/test/resources/openaireguidelinesV4/v4_literature_all_invalid_guidelines_record.xml",
// "src/test/resources/openaireguidelinesV4/v4_literature_all_guidelines_record.xml",
//"src/test/resources/openaireguidelinesV4/v4_literature_all_invalid_guidelines_record.xml",
"src/test/resources/openaireguidelinesV4/v4_literature_all_guidelines_record.xml",
// "src/test/resources/openaireguidelinesV4/oai_mediarep_org_doc_2534.xml",
// "src/test/resources/openaireguidelinesV4/01_gv4.xml"
};