2017-08-15 4 views
1

A ont un schéma XSD qui décrit un objet XML (exemple simplifié):Est-il possible d'ajouter une nouvelle balise XML afin qu'elle soit transparente pour une validation XSD?

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      targetNamespace="http://my-custom-ns.com"> 
    <xs:element name="item"> 
     <xs:complexType> 
      <xs:sequence> 
       <xs:element name="active" type="xs:boolean"/> 
       <xs:element name="value" type="xs:string"/> 
      </xs:sequence> 
     </xs:complexType> 
    </xs:element> 
</xs:schema> 

Ce schéma est intégré dans une application comme une ressource et installé sur plusieurs postes de travail. L'application consomme des fichiers XML et les valide par rapport à ce schéma. Voici un (simplifié) exemple d'un tel XML:

<my:item xmlns:my="http://my-custom-ns.com"> 
    <active>true</active> 
    <value>foo</value> 
</my:item> 

Maintenant, je veux que mes fichiers XML pour obtenir un nouvel élément (une nouvelle étiquette) sans changer le XSD:

<my:item xmlns:my="http://my-custom-ns.com"> 
    <active>true</active> 
    <value>foo</value> 
    <tag>bar</tag> 
</my:item> 

I ne change pas le XSD, donc évidemment la validation échoue sur une nouvelle étiquette. Existe-t-il un moyen d'avoir une nouvelle balise dans le fichier XML afin qu'elle "traverse" la validation de manière transparente (c'est-à-dire qu'elle soit complètement ignorée)?

J'ai essayé d'ajouter un nouvel espace de noms dans le fichier XML dans l'espoir que la validation XSD ignorera, mais cela n'a pas aidé:

<my:item xmlns:my="http://my-custom-ns.com" xmlns:new="http://new-ns.com"> 
    <active>true</active> 
    <value>foo</value> 
    <new:tag>bar</new:tag> 
</my:item> 

L'arrière-plan est le suivant: il devrait être possible pour l'application actuelle version pour traiter les fichiers XML qui ont un tag supplémentaire, simple en l'ignorant. Mais l'application a une forte validation contre un XSD, comme je l'ai décrit ci-dessus. Peut-être qu'il y a une autre façon de le faire?

+0

Comment votre application verrait-elle ce nouvel élément s'il se trouvait dans un espace de noms différent? Je crois que cela n'est guère possible sans modification du schéma. –

+0

@AlexeyR., L'espace de noms était juste un exemple (malchanceux). En fait, j'ai besoin d'un moyen de rendre une balise totalement transparente à la validation XSD par rapport à un schéma qui n'autorise pas explicitement les balises * undefined *. Semble être impossible, j'ai peur. – dymanoid

Répondre

0

Oui et non. Il y a un moyen d'y parvenir si le schéma original a une étiquette spéciale.

Si vous savez à l'avance que les documents peuvent avoir des éléments supplémentaires, mais vous ne connaissez pas ces éléments à l'avance, les schémas peuvent être conçus de manière avant-compatible à l'aide xs:any balises, comme ceci:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="http://my-custom-ns.com"> 
    <xs:element name="item"> 
     <xs:complexType> 
      <xs:sequence> 
       <xs:element name="active" type="xs:boolean"/> 
       <xs:element name="value" type="xs:string"/> 
       <xs:any namespace="##other" processContents="lax" minOccurs="0"/> 
      </xs:sequence> 
     </xs:complexType> 
    </xs:element> 
</xs:schema> 

ce document est valide par rapport au schéma ci-dessus:

<my:item xmlns:my="http://my-custom-ns.com" xmlns:new="http://new-ns.com"> 
    <active>true</active> 
    <value>foo</value> 
</my:item> 

ainsi que celui-ci:

<my:item xmlns:my="http://my-custom-ns.com" xmlns:new="http://new-ns.com"> 
    <active>true</active> 
    <value>foo</value> 
    <new:tag>bar</new:tag> 
</my:item> 

Le comportement de peut être adapté en modifiant les valeurs des attributs namespace et processContents. Cependant, si le schéma est déjà fait et est en dehors de votre contrôle, les éléments supplémentaires ne peuvent apparaître que si le concepteur d'origine le permet.

Un exemple de ceci est ... XML Schema lui-même. Les éléments de schéma XML peuvent contenir des attributs arbitraires dans les espaces de noms étrangers (plusieurs normes sont construites sur le schéma XML de cette façon), et cela parce que le schéma XML des schémas autorise explicitement les attributs dans d'autres espaces de noms.

+0

Oui, j'ai pensé utiliser l'élément de schéma 'xs: any'. Mais malheureusement, le schéma est déjà sur les machines cibles et ne peut pas être changé sans mettre à jour la version de l'application (ce qui n'est pas possible pour des raisons particulières). Et apparemment, le concepteur de schéma d'origine n'a pas permis d'utiliser des éléments supplémentaires ... – dymanoid

0

Une autre solution consisterait à restructurer l'instance XML. XML Schema permet d'imbriquer XML validée par schéma (sans modification) dans une instance plus grande.

<new:wrapper xmlns:my="http://my-custom-ns.com" xmlns:new="http://new-ns.com"> 
    <my:item> 
    <active>true</active> 
    <value>foo</value> 
    </my:item> 
    <new:tag>bar</new:tag> 
</new:wrapper> 

Ceci peut être réalisé avec un nouveau schéma qui importe l'ancien et fait référence à l'élément my:item.

Le schéma précédent ne nécessite aucune modification tant que le code XML imbriqué est strictement validé.

+0

Eh bien, ce serait possible si je pouvais fournir le nouveau schéma aux utilisateurs de l'application. Mais malheureusement, la version de l'application ne peut pas être mise à jour pour des raisons particulières, donc je suis coincé avec l'ancien. – dymanoid