Pour chaque classe de méta-donnée, il existe un type XML portant le même nom que dans la spécification abstraite
(par exemple mdb:MD_Metadata
et cit:CI_Citation
).
Tous ces types peuvent être employés comme racine d’un document XML.
Ainsi, il est possible d’écrire un document représentant un objet MD_Metadata
complet,
ou d’écrire un document représentant seulement un objet CI_Citation
.
Le standard ISO 19139 dispose le contenu de ces objets d’une manière inhabituelle:
pour chaque propriété dont le type de la valeur est lui-même une autre classe du standard ISO 19139,
la valeur est enveloppée dans un élément qui représente son type plutôt que d’être écrite directement.
Par exemple dans un objet de type CI_Citation
,
la valeur de la propriété citedResponsibleParty
est enveloppée dans un élément CI_Responsibility
.
Cette pratique double la profondeur de l’arborescence, en introduisant une duplication
à tous les niveaux pour chaque valeur, comme dans l’exemple suivant:
<MD_Metadata> <identificationInfo> <MD_DataIdentification> <citation> <CI_Citation> <citedResponsibleParty> <CI_Responsibility> <party> <CI_Party> <contactInfo> <CI_Contact> <onlineResource> <CI_OnlineResource> <linkage> <URL>https://www.ogc.org</URL> </linkage> </CI_OnlineResource> </onlineResource> </CI_Contact> </contactInfo> </CI_Party> </party> </CI_Responsibility> </citedResponsibleParty> </CI_Citation> </citation> </MD_DataIdentification> </identificationInfo> </MD_Metadata>
L’exemple précédent, comme tous les documents conformes à ISO 19139, est donc constitué d’une alternance systématique de deux types d’éléments XML imbriqués:
Il y a d’abord le nom de la propriété, qui commence toujours par une lettre minuscule (en ignorant les préfixes).
Dans les API Java, chaque propriété correspond à une méthode de la classe englobante.
Dans l’exemple ci-haut, mdb:identificationInfo
(une propriété de la classe MD_Metadata
)
correspond à la méthode Metadata.getIdentificationInfo()
.
Sous chaque propriété se trouve le type de la valeur, sauf si elle a été remplacée par une référence
(la sous-section suivante suivante approfondira ce sujet).
Le type de la valeur est un élément XML dont le nom commence toujours par une lettre majuscule, en ignorant les préfixes.
Dans l’exemple ci-haut nous avions MD_DataIdentification
, qui correspond à l’interface Java DataIdentification
.
C’est cet élément XML qui contient les valeurs de la propriété.
Afin de réduire la complexité des bibliothèques, GeoAPI et Apache SIS n’exposent publiquement qu’une vision unifiée de ces deux types d’éléments. L’API public correspond essentiellement au deuxième groupe. Toutefois, lors de l’écriture d’un document XML, des éléments du premier groupe doivent être temporairement recréés. Les classes qui y correspondent sont définies dans des paquets internes de SIS. Ces classes peuvent être ignorées, sauf si le développeur souhaite implémenter ses propres classes dont les instances devront être lues et écrites par JAXB.
L’élément englobant peut contenir un attribut id
ou uuid
.
Si un de ces attributs est présent, l’élément englobé peut être complètement omis;
il sera remplacé au moment de la lecture par l’élément référencé par l’attribut.
Dans l’exemple suivant, la partie gauche définie un élément associé à l’identifiant “mon_id
”,
alors que la partie droite référence cet élément:
<MD_MetaData> <identificationInfo> <MD_DataIdentification id="mon_id"> <!-- insérer ici des propriétés filles --> </MD_DataIdentification> </identificationInfo> </MD_MetaData>
<MD_MetaData> <identificationInfo xlink:href="#mon_id"/> </MD_MetaData>
Le choix de l’attribut à utiliser dépend de la portée de l’élément référencé:
id
n’est valide qu’à l’intérieur du document XML
qui définit l’objet ainsi référencé.
uuid
peut être valide à l’extérieur du document XML,
mais quelqu’un doit maintenir une base de données fournissant les objets pour chaque UUID donnés.
xlink:href
peut faire référence à un autre document XML accessible sur internet.
Dans la bibliothèque SIS, tous les objets susceptibles d’être identifiés dans un document XML
implémentent l’interface org.apache.sis.xml.IdentifiedObject
.
Chaque instance de cette interface fournit une vue de ses identifiants sous forme de Map<Citation,String>
,
dans lequel la clé Citation
identifie le type d’identifiant et la valeur est l’identifiant lui-même.
Quelques constantes représentant différents types d’identifiants sont énumérées dans IdentifierSpace
,
notamment ID
, UUID
et HREF
.
Chacune de ces clés peut être associée à une valeur d’un type différent (habituellement String
,
UUID
ou URI
) selon la clé.
Par exemple le code suivant définit une valeur pour l’attribut uuid
:
import org.apache.sis.metadata.iso.DefaultMetadata;
import org.apache.sis.xml.IdentifierSpace;
import java.util.UUID;
public class MyClass {
public void myMethod() {
UUID identifier = UUID.randomUUID();
DefaultMetadata
metadata = new DefaultMetadata
();
metadata.getIdentifierMap().putSpecialized
(IdentifierSpace.UUID, identifier);
}
}
Bien que ce mécanisme aie été définit dans le but de mieux supporter les représentations des
attributs XML du groupe gco:ObjectIdentification
,
il permet aussi de manière opportuniste de manipuler d’autres types d’identifiants.
Par exemple les attributs ISBN
et ISSN
de Citation
peuvent être manipulés de cette manière.
Les méthodes de l’interface IdentifiedObject
fournissent donc un endroit unique
où peuvent être manipulés tous types d’identifiants (pas seulement XML) associés à un objet.
Lorsqu’une propriété n’est pas définie, la méthode correspondante de GeoAPI retourne généralement null
.
Toutefois les choses se compliquent lorsque la propriété manquante est une valeur considérée comme obligatoire par le standard ISO 19115.
Le standard ISO 19139 autorise l’omission de propriétés obligatoires à la condition d’indiquer pourquoi la valeur est manquante.
Les raisons peuvent être que la propriété ne s’applique pas (inapplicable
),
que la valeur existe probablement mais n’est pas connue (unknown
),
que la valeur pourrait ne pas exister (missing
),
qu’elle ne peut pas être divulguée (withheld
), etc.
La transmission de cette information nécessite l’utilisation d’un objet non-nul même lorsque la valeur est manquante.
SIS procède en retournant un objet qui, en plus d’implémenter l’interface GeoAPI attendue,
implémente aussi l’interface org.apache.sis.xml.NilObject
.
Cette interface marque les instances dont toutes les méthodes retournent une collection vide,
un tableau vide, null
, NaN
, 0
ou false
,
dans cet ordre de préférence selon ce que les types de retours des méthodes permettent.
Chaque instance implémentant NilObject
fournit une méthode
getNilReason()
indiquant pourquoi l’objet est nul.
Dans l’exemple suivant, la partie gauche montre un élément CI_Citation
contenant un élément CI_Series
, alors que dans la partie droite la série est inconnue.
Si l’élément CI_Series
avait été complètement omis,
alors la méthode Citation.getSeries()
retournerait null
en Java.
Mais en présence d’un attribut nilReason
, l’implémentation SIS
de getSeries()
retournera plutôt un objet implémentant à la fois les interfaces
Series
et NilReason
,
et dont la méthode getNilReason()
retournera la constante UNKNOWN
.
<CI_Citation> <series> <CI_Series> <!-- insérer ici des propriétés filles --> </CI_Series> </series> </CI_Citation>
<CI_Citation> <series nilReason="unknown"/> </CI_Citation>