J'ai des documents xml qui suivent un schéma où la plupart des éléments définis sont autorisés à être la racine d'une instance valide. J'ai aussi plusieurs v2.0 de xslt qui le traduisent de différentes manières (le mettre dans une forme normale, une forme compacte, un dialecte différent, ...) Ces xslt sont tous basés sur une transformation d'identité avec des templates ajoutés pour faire le désiré modification. Le problème est qu'il existe une prolifération d'attributs d'espace de noms car certains éléments proviennent de l'extérieur de l'espace de noms par défaut.xslt: conserver la déclaration d'espace de nom à la racine lorsque l'élément racine n'est pas connu à l'avance
J'ai essayé les procédures recommandées pour insérer l'espace de noms sur l'élément racine, mais je n'arrive pas à le faire correctement. Les problèmes sont: 1. la transformation peut changer le nom, et parfois le contenu de l'élément racine, donc j'ai toujours besoin des modèles pour chacun des éléments globaux, et puisque je ne sais pas lequel sera racine, je ne peut pas insérer des éléments d'espace de nommage si nécessaire (je ne sais pas où ils seront nécessaires pour un document particulier 2. J'ai pensé mettre en œuvre ceci comme multi-pass, ou simplement comme un xslt indépendant, puisque je veux le même résultat Dans ce cas, ce dont j'aurais besoin est une transformation d'identité qui prend tous les espaces de noms et les préfixes de tous les éléments du document, et les insère dans la racine, ce qui, je l'espère, supprimera automatiquement les attributs les enfants? Cependant, j'ai essayé le suivant
<?xml version="1.0" ?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template name="start" match="/">
<xsl:copy>
<xsl:for-each select="*">
<xsl:copy>
<xsl:for-each select="descendant::*">
<xsl:call-template name="add-ns">
<xsl:with-param name="ns-namespace">
<xsl:value-of select="namespace-uri()"/>
</xsl:with-param>
<xsl:with-param name="ns-prefix">
<xsl:value-of
select=" prefix-from-QName(QName(namespace-uri(),name()))"/>
</xsl:with-param>
</xsl:call-template>
</xsl:for-each>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template name="add-ns">
<xsl:param name="ns-prefix" select="'x'"/>
<xsl:param name="ns-namespace" select="'someNamespace'"/>
<xsl:namespace name="{$ns-prefix}" select="$ns-namespace"/>
</xsl:template>
<xsl:template match="node()|@* ">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Et cela fonctionne pour tous les préfixes qui apparaissent sur les éléments, mais il n'attrape pas les préfixes des attributs. Voici un document de test:
<RuleML xmlns="http://www.ruleml.org/0.91/xsd">
<Assert textiri="xy>z">
<Importation xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="abc"
textiri="urn:common-logic:demo1"
xlink:href="http://common-logic.org/x>cl/demos.xml"/>
<a:anything xmlns:a="http://anything.org"
xmlns:xlink="http://www.w3.org/1999/xlink"/>
</Assert>
</RuleML>
Je veux produire:
<RuleML xmlns="http://www.ruleml.org/0.91/xsd" xmlns:a="http://anything.org" xmlns:xlink="http://www.w3.org/1999/xlink" >
<Assert textiri="xy>z">
<Importation xml:id="abc"
textiri="urn:common-logic:demo1"
xlink:href="http://common-logic.org/x>cl/demos.xml"/>
<a:anything/>
</Assert>
</RuleML>
mais je reçois
<RuleML xmlns="http://www.ruleml.org/0.91/xsd" xmlns:a="http://anything.org">
<Assert textiri="xy>z">
<Importation xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="abc"
textiri="urn:common-logic:demo1"
xlink:href="http://common-logic.org/x>cl/demos.xml"/>
<a:anything xmlns:xlink="http://www.w3.org/1999/xlink"/>
</Assert>
</RuleML>
Tara