2010-06-30 6 views
2

feuille de style XSL doit générer le code ci-dessous pour Internet Explorer:Comment préserver l'espace de noms XML dans la sortie XSLT?

<xml:namespace prefix="vml" ns="urn:schemas-microsoft-com:vml"/> 

Mais quand j'exécutons suivant modèle avec tout XML

<xsl:template match="*|node()"> 
    <xml:namespace prefix="vml" 
        ns="urn:schemas-microsoft-com:vml"/> 
</xsl:template> 

IE lancers francs Erreur d'analyse: La feuille de style ne contient pas élément de document. Dans le même temps, Firefox supprime espace de noms xml dans la sortie ...

Alors, comment puis-je conserver espace de noms XML dans ma sortie?

Important

a. La méthode de sortie que j'utilise est html

b. code suivant ne résout pas mon problème:

<xsl:template match="*|node()"> 
    <namespace prefix="vml" 
       xmlns="http://www.w3.org/XML/1998/namespace" 
       ns="urn:schemas-microsoft-com:vml"/> 
</xsl:template> 
+0

Dois-je comprendre que vous voulez ajouter un nœud d'espace de noms à chaque élément? –

+0

@Sawa: Je dois dire que je suis avec Dimitre pour décourager l'utilisation de xml: namespace et d'autres éléments non standard autorisés par MS. De plus, cela peut être fait avec la déclaration d'espace de nom propre 'xmlns: vml =" urn: schémas-microsoft-com: vml "' –

Répondre

2

Vous ne pouvez pas utiliser le préfixe xml conservé. Utilisez quelque chose comme ceci:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dummy="dummy"> 
<xsl:namespace-alias stylesheet-prefix="dummy" result-prefix="xml"/> 
<xsl:template match="/"> 
    <dummy:namespace prefix="vml" 
        ns="urn:schemas-microsoft-com:vml"/> 
</xsl:template> 
</xsl:stylesheet> 

Avec une entrée, vous obtenez ce résultat:

<xml:namespace prefix="vml" ns="urn:schemas-microsoft-com:vml" /> 
1

Si vous voulez littéralement le résultat comme indiqué dans la question, ce qui est très simple à réaliser:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes"/> 

<xsl:template match="/"> 
    <xml:namespace prefix="vml" ns="urn:schemas-microsoft-com:vml"/> 
</xsl:template> 
</xsl:stylesheet> 

Cette transformation, lorsqu'elle est appliquée sur tout document XML (non utilisé), produit le résultat souhaité :

<xml:namespace prefix="vml" ns="urn:schemas-microsoft-com:vml"/> 

Cependant, il me semble que vous voulez ajouter un nœud d'espace de noms à chaque élément d'un document XML donné (si ce n'est pas, me faire savoir via un commentand Je vais supprimer cette répondre).

Si oui, voici un moyen simple et efficace:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:vml="urn:schemas-microsoft-com:vml" 
    exclude-result-prefixes="vml"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:variable name="vNamespace" select= 
    "document('')/*/namespace::*[name()='vml']"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="/*"> 
    <xsl:copy> 
     <xsl:copy-of select="$vNamespace"/> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 

lorsqu'il est appliqué à tout document, par exemple celui-ci:

<t> 
    <a x="3"> 
     <b y="4"/> 
    </a> 
</t> 

le résultat recherché est produit:

<t xmlns:vml="urn:schemas-microsoft-com:vml"> 
    <a x="3"> 
     <b y="4"/> 
    </a> 
</t> 

Cela peut être déroutant à première vue car seul l'élément supérieur du résultat a visiblement le nœud d'espace de noms souhaité. Cependant, par définition (regardez le XML Namespace spec) si un élément à la racine d'un (sous-) arbre a un nœud d'espace de nommage donné, alors tous ses éléments descendants ont aussi ce nœud d'espace de nommage.Même si vous copiez l'espace de noms dans chaque élément, le sérialiseur XSLT le supprimera de la représentation sérialisée (texte) de tous sauf l'élément supérieur.

Dans XSLT 2.0 vous pouvez simplement utiliser l'instruction <xsl:namespace>:

<xsl:namespace name="vml" select="urn:schemas-microsoft-com:vml"/> 
+0

Je pense que votre réponse ne couvre pas tous les scénarios. Si la feuille de style doit être analysée côté client avec IE, vous obtiendrez les résultats suivants: 'El prefijo del espacio des nombres pas puede comenzar avec la réserve" xml "' –

+1

@Alejandro: Je n'étais pas au courant de ce comportement de MSXML3 (que IE utilise). Hmmm ... Cela peut être considéré à la fois comme une fonctionnalité et comme un bug. Le fait est que tous les autres processeurs XSLT avec lesquels je travaille le permettent. En fait MSXML4 l'autorise, ce qui signifie qu'ils ont corrigé le bogue MSXML3 dans MSXML4. Peu importe, essayer d'utiliser des éléments non standard dans l'espace de noms 'xml:' est un abus grossier et je déconseillerais à l'auteur de le faire. –

+0

Je suis avec vous pour décourager l'utilisation de 'xml: namespace' et d'autres éléments non standard autorisés par MS. De plus, cela peut être fait avec la déclaration d'espace de noms propre 'xmlns: vml =" urn: schemas-microsoft-com: vml " –

Questions connexes