Résumé

  • RFC 3151 normalisait une chaîne d’identifiant public, puis transcrivait espaces, séparateurs structuraux et caractères littéraux réservés dans une forme déterministe urn:publicid: ; la conversion correcte ne validait ni propriétaire ni ressource.
  • L’équivalence lexicale restait étroite : après normalisation, deux URN n’étaient équivalentes que si elles étaient identiques. Un même nom pouvait encore rencontrer des catalogues, octets et comportements différents.
  • La résolution demeurait contextuelle — catalogue, chemin local, connaissance intégrée ou cache — et exigeait des reçus distincts pour la sélection, le mappage, la récupération, l’analyse et l’effet applicatif.

Une chaîne ancienne devait entrer dans l’architecture URI

Une entité externe XML disposait de deux identifiants. L’identifiant système était une URI par définition. L’identifiant public n’était qu’une chaîne. Dans la pratique héritée de SGML, le premier désignait souvent un emplacement local tandis que le second servait de nom plus global et plus durable.

Les nouvelles spécifications du Web demandaient de plus en plus que tout identifiant externe soit une URI. Abandonner les noms installés aurait rompu catalogues, documents et logiciels. RFC 3151 choisit une compatibilité minimale : le namespace formel publicid permettait d’exprimer la chaîne sous la forme urn:publicid:{transcription}.

La silhouette d’une URI pouvait donner au résultat une autorité qu’il ne possédait pas. La persistance et l’unicité restaient celles de l’identifiant source. Un propriétaire non enregistré ou une politique faible ne devenaient pas solides par l’ajout du préfixe.

Le texte était Informational et précisait qu’il ne définissait aucun standard Internet. Ses exemples étaient pédagogiques, sans garantie d’existence réelle. Une paire d’exemple illustrait donc l’algorithme ; elle ne prouvait ni enregistrement, ni catalogue déployé, ni ressource accessible.

La normalisation effaçait volontairement une trace

Avant l’encodage, toute suite d’espaces, tabulations, retours chariot ou sauts de ligne devenait un seul espace ordinaire. Les blancs initiaux et finaux disparaissaient. Le RFC supposait cette normalisation déjà accomplie.

Deux captures dont seule l’indentation différait pouvaient alors produire le même nom normalisé. Cette perte était utile à la comparaison, mais irréversible si l’on ne conservait que l’URN. Il fallait donc archiver la chaîne originale, son encodage, le résultat normalisé et la version de la règle.

Chaque espace normalisé devenait +. Des signes plus adjacents issus des blancs ne pouvaient pas apparaître, puisque les suites avaient été réduites auparavant. En revanche, un véritable + dans la source devenait %2B. Le premier symbolisait un espace ; le second préservait un caractère littéral.

Un système qui normalisait après la transcription inversait la preuve. Un champ final pouvait sembler correct tout en cachant un ordre d’opérations erroné. Le reçu devait montrer chaque étape, non seulement le dernier texte.

La structure était transportée, pas certifiée

Les Formal Public Identifiers formaient un sous-ensemble structuré. Ils combinaient généralement propriétaire, classe, description, langue ou séquence désignatrice et parfois version d’affichage. Les champs employaient souvent //, et :: pouvait structurer du texte interne.

RFC 3151 transformait // en : et :: en ;. Cette convention conservait l’allure structurée sans demander au traducteur de reconnaître toute la grammaire SGML. Déterminer qu’une chaîne était réellement un FPI valide restait hors périmètre.

Ainsi, un deux-points produit par la transcription témoignait d’un double slash dans la source. Il ne certifiait ni la validité de la structure, ni l’enregistrement du propriétaire, ni le sens des champs.

Les occurrences littérales devaient rester distinctes. Un : qui ne faisait pas partie de :: devenait %3A ; un / isolé devenait %2F ; un point-virgule devenait %3B. Apostrophe, point d’interrogation, dièse et pourcentage recevaient eux aussi un encodage. L’ordre et la position des remplacements faisaient donc partie du mécanisme.

Un test aller-retour pouvait démontrer qu’une implémentation préservait le nom normalisé. Il ne démontrait toujours pas qu’un propriétaire l’avait attribué ni qu’une ressource correspondante existait.

L’égalité lexicale ne disait rien des octets

Le RFC donna une règle volontairement stricte : après normalisation de la source, deux URN publicid étaient équivalentes si et seulement si elles étaient lexicalement identiques. Il n’introduisit ni repli de casse, ni alias de propriétaire, ni comparaison sémantique des champs.

Cette limite empêchait une commodité locale de devenir loi du namespace. Deux graphies ne devenaient pas égales parce qu’un catalogue les dirigeait vers le même fichier. Et deux chaînes égales ne garantissaient pas le même contenu.

Une ressource pouvait posséder plusieurs identifiants publics. Inversement, une même URN pouvait rencontrer des piles de catalogues différentes, des chemins de base distincts ou des caches d’âges différents. Égalité du nom, égalité du mappage, égalité des octets et égalité du comportement étaient quatre observations.

Les RFC ultérieurs sur URI et URN éclairent l’évolution de la syntaxe et de l’enregistrement. Ils ne réécrivent pas le catalogue actif en 2001 et ne transforment pas l’équivalence lexicale de RFC 3151 en équivalence de ressource.

Le namespace héritait des faiblesses du propriétaire

Les FPI dont le propriétaire était enregistré devaient être uniques. Les noms informels et les propriétaires non enregistrés pouvaient être uniques ou non ; aucune politique d’exécution uniforme n’était affirmée.

La persistance suivait la même logique. Un propriétaire enregistré constituait généralement un meilleur socle, sans garantir disponibilité, maintenance ou contenu. Le mécanisme IDN fondé sur un nom de domaine héritait au moins des faiblesses de persistance des domaines.

Le mot URN ne constituait donc pas une promotion automatique. Encoder un nom fragile ne le rendait pas durable. Enregistrer un propriétaire ne maintenait pas un catalogue. Une règle d’attribution ne prouvait pas son application. Un nom stable ne figeait pas les représentations servies.

Pour créer une URN d’une ressource sans identifiant public, il fallait d’abord créer cet identifiant selon ses propres règles. Comme plusieurs noms pouvaient viser une ressource, la provenance exigeait propriétaire, politique, date et contexte d’attribution.

La résolution gardait plusieurs chemins

Le texte citait les catalogues OASIS, le mappage de composants vers des chemins locaux, un ensemble connu directement par le logiciel et des mécanismes propres aux URI comme les caches. Il ne définissait pas un résolveur mondial caché derrière urn:publicid:.

L’ordre des catalogues, les règles de réécriture, l’URI de base, le montage local, l’accès réseau et la fraîcheur du cache pouvaient modifier le résultat. Un match de catalogue prouvait qu’une règle avait choisi une cible. Il ne prouvait pas sa récupération.

La lecture du fichier ou de la réponse produisait un autre reçu. Son empreinte établissait les octets. Le parseur, sa version et sa politique d’entités déterminaient ensuite l’interprétation. Enfin, l’application produisait ou non le résultat attendu. resolved=true écrasait cette succession.

Le RFC ne spécifiait aucun mécanisme de validation. Il n’ajoutait pas de considération de sécurité au-delà de celles des URN et de leur résolution. Cela n’authentifiait ni le propriétaire, ni le catalogue, ni le cache, ni la cible. Une transcription parfaite pouvait conduire à un fichier local obsolète ou substitué.

Le code en cours pouvait corriger le nom parfait

Imaginons une URN parfaitement construite. Le premier catalogue la transforme en chemin local ; le fichier existe ; l’analyse réussit. Si les octets appartiennent à une ancienne version, toutes les couches syntaxiques sont correctes et le résultat applicatif reste faux.

Sur une seconde machine, la même URN peut sélectionner un autre catalogue et une autre DTD. Le nom est identique, le comportement diverge. Un cache peut retenir une ancienne cible après un changement de politique. Une table intégrée peut fonctionner alors que la ressource réseau a disparu.

La table de RFC 3151 garde son autorité sur la transcription. Le code exécuté répond aux questions suivantes : quel résolveur a couru, quelle règle a gagné, quels octets sont arrivés et que leur a fait l’application. Aucune couche ne doit emprunter le reçu de la suivante.

L’accomplissement historique était précisément borné. Un nom public ancien pouvait franchir la frontière de syntaxe sans devenir une localisation. Franchir cette frontière ne terminait pas le trajet vers la ressource.

Sources