2010-01-05 7 views
0

Je souhaite éviter de créer un espace de noms répété dans ma sortie XSLT.XSLT: Utilisation de l'espace de noms du noeud parent

(j'utilise XSLT pour masser certains XML afin que DataContractSerializer Microsoft voit apte à traiter effectivement correctement. L'une des choses que la DCS ne semble pas aimer est de définir plusieurs fois le même espace de noms.)

Je prends toutes les « caractéristiques » des éléments sous l'élément XXX et les regrouper dans un nouvel élément de tableau comme ceci:

<xsl:stylesheet version="1.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:feature="some namespace"> 
<xsl:template match="feature:XXX"> 
    <xsl:copy> 
    <feature:Characteristics> 
     <xsl:apply-templates select="feature:Characteristics"/> 
    </feature:Characteristics> 
    <xsl:copy-of select="*[not(self::feature:Characteristics)]" /> 
    </xsl:copy> 
</xsl:template> 
<xsl:template match="feature:Characteristics"> 
    <arrays:unsignedShort xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays"> 
    <xsl:value-of select="." /> 
    </arrays:unsignedShort> 
</xsl:template> 
</xsl:stylesheet> 

l'espace de noms « caractéristique » est définie au début du fichier XSLT. Cependant la valeur "feature" ne va pas être trouvée dans le XML source, ce sera un préfixe arbitraire (habituellement "h"). Le problème est que si j'utilise ce XSLT alors l'espace de noms est assigné à 2 préfixes dans le XML de sortie: l'espace de noms original de l'entrée XML (habituellement "h") et "feature" générés par le XSLT. (Alors que XML valide, cela confond Microsoft pauvre.)

Donc je voudrais éviter complètement de définir l'espace de noms "feature" dans le XML de sortie en se référant à la place plutôt à l'espace de noms de l'élément actuel. J'ai essayé des variantes sur cela, mais je ne sais pas comment définir la valeur d'espace de noms de l'élément xsl: correctement afin d'obtenir le préfixe actuel d'espace de noms de nœud de contexte ...

<xsl:stylesheet version="1.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:feature="some namespace"> 
    <xsl:template match="feature:XXX"> 
    <xsl:copy> 
    <xsl:element name="Characteristics" namespace="{???}"> 
     <xsl:apply-templates select="feature:Characteristics"/> 
    </xsl:element> 
    <xsl:copy-of select="*[not(self::feature:Characteristics)]" /> 
    </xsl:copy> 
</xsl:template> 
    <xsl:template match="feature:Characteristics"> 
    <arrays:unsignedShort xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays"> 
    <xsl:value-of select="." /> 
    </arrays:unsignedShort> 
</xsl:template> 
</xsl:stylesheet> 

entrée de l'échantillon:

<h:XXX xmlns:h="http://stackoverflow.com"> 
<h:Characteristics>7</h:Characteristics> 
<h:Characteristics>11</h:Characteristics> 
<h:Characteristics>12</h:Characteristics> 
<h:ProductName>blah</h:ProductName> 
<h:Vendor>blah</h:Vendor> 
<h:Version></h:Version> 
</h:XXX> 

namespaces Répéter (mauvais):

<h:XXX xmlns:h="http://stackoverflow.com"> 
<feature:Characteristic xmlns:feature="http://stackoverflow.com"> 
     <arrays:unsignedShort xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays">7</arrays:unsignedShort> 
     <arrays:unsignedShort xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays">11</arrays:unsignedShort> 
     <arrays:unsignedShort xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays">12</arrays:unsignedShort> 
</feature:Characteristic> 
<h:ProductName>blah</h:ProductName> 
<h:Vendor>blah</h:Vendor> 
<h:Version></h:Version> 
</h:XXX> 

sortie souhaitée:

<h:XXX xmlns:h="http://stackoverflow.com"> 
<h:Characteristic> 
     <arrays:unsignedShort xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays">7</arrays:unsignedShort> 
     <arrays:unsignedShort xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays">11</arrays:unsignedShort> 
     <arrays:unsignedShort xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays">12</arrays:unsignedShort> 
</h:Characteristic> 
<h:ProductName>blah</h:ProductName> 
<h:Vendor>blah</h:Vendor> 
<h:Version></h:Version> 
</h:XXX> 

Ce XSLT fonctionne presque, mais elle implique hardcoding la valeur « h », et je voudrais soutenir une valeur arbitraire à la place:

<?xml version ="1.0" encoding="iso-8859-1"?> 
    <xsl:stylesheet version="1.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:feature="some ns" 
       xmlns:h="some ns" 
       exclude-result-prefixes="h"> 

<xsl:template match="feature:XXX"> 
    <xsl:copy> 
    <h:Characteristic> 
     <xsl:apply-templates select="feature:Characteristics"/> 
    </h:Characteristic> 
    <xsl:copy-of select="*[not(self::feature:Characteristics)]" /> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="feature:Characteristics"> 
    <arrays:unsignedShort xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays"> 
    <xsl:value-of select="." /> 
    </arrays:unsignedShort> 
</xsl:template> 

</xsl:stylesheet> 
+0

peut vous fournir quelques exemples s'il vous plaît données? –

+0

modifié le poste avec des données – evilfred

+0

Si les éléments utilisent des préfixes d'espace de noms différents ne devrait pas importer au moteur d'analyse. Ils se développeront dans le même espace de noms et représenteront le même nom d'élément. Quel genre d'erreurs rencontrez-vous? –

Répondre

1

Si vous souhaitez préfixes d'espaces de noms cohérents alors vous aurez besoin de générer de nouveaux éléments, plutôt que copie de. Définissez votre préfixe d'espace de noms à ce que vous voulez qu'il soit (fonctionnalité, h, etc) dans le XSLT.

La XSLT suivante:

<xsl:stylesheet version="1.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:feature="http://stackoverflow.com" 
       xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays"> 
    <xsl:output method="xml" indent="yes" /> 

    <xsl:template match="feature:XXX"> 
    <xsl:element name="feature:XXX"> 
    <feature:Characteristic> 
     <xsl:apply-templates select="feature:Characteristics"/> 
    </feature:Characteristic> 
    <xsl:apply-templates select="*[not(self::feature:Characteristics)]" /> 
    </xsl:element> 
    </xsl:template> 

    <xsl:template match="feature:Characteristics"> 
    <xsl:element name="arrays:unsignedShort"> 
     <xsl:value-of select="." /> 
    </xsl:element> 
    </xsl:template> 

    <xsl:template match="*"> 
    <xsl:element name="feature:{local-name()}" > 
     <xsl:value-of select="." /> 
    </xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 

le résultat suivant:

<?xml version="1.0" encoding="UTF-16"?> 
<feature:XXX xmlns:feature="http://stackoverflow.com"> 
<feature:Characteristic xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays"> 
    <arrays:unsignedShort>7</arrays:unsignedShort> 
    <arrays:unsignedShort>11</arrays:unsignedShort> 
    <arrays:unsignedShort>12</arrays:unsignedShort> 
</feature:Characteristic> 
<feature:ProductName>blah</feature:ProductName> 
<feature:Vendor>blah</feature:Vendor> 
<feature:Version></feature:Version> 
</feature:XXX> 
+0

Merci, très élégant – evilfred

1

Je viens enlevé que feature espace de noms; si j'ai bien compris, il contiendra le même URI que h, non?

<xsl:stylesheet version="1.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:h="http://stackoverflow.com"> 
    <xsl:output method="xml" indent="yes" /> 
    <xsl:template match="h:XXX" > 
    <xsl:copy> 
     <h:Characteristics> 
     <xsl:apply-templates select="h:Characteristics"/> 
     </h:Characteristics> 
     <xsl:copy-of select="*[not(self::h:Characteristics)]" /> 
    </xsl:copy> 
    </xsl:template> 
    <xsl:template match="h:Characteristics"> 
    <arrays:unsignedShort 
     xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays"> 
     <xsl:value-of select="." /> 
    </arrays:unsignedShort> 
    </xsl:template> 
</xsl:stylesheet> 
+0

L'espace de noms h sera défini une deuxième fois sur l'élément Caractéristiques de la sortie, ce qui ne fonctionnera pas pour moi. – evilfred

+0

Je n'ai pas vu ça dans mon environnement; comment testez-vous cette transformation XSLT? –

+0

en C# // Chargez la feuille de style. XslCompiledTransform xslt = new XslCompiledTransform(); xslt.Load (convertFilename); // Exécute la transformation et affiche les résultats dans un fichier. xslt.Transform (sourceFile, "blah.xml"); – evilfred

1

Cela semble fonctionner pour moi, je suis sûr qu'il doit y avoir un moyen plus facile mais je ne peux pas penser en ce moment. Tout ceci utilise-t-il la fonction name() pour obtenir le nom préfixé du nom racine, substring-before() pour obtenir le préfixe puis reconstruire les valeurs et les émettre comme texte non échappé.

<xsl:stylesheet version="1.0" 
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
      xmlns:feature="http://stackoverflow.com" 
     exclude-result-prefixes="feature" > 
<xsl:template match="feature:XXX"> 
    <xsl:variable name="p" select="substring-before(name(), ':')"/> 
    <xsl:copy> 
    <xsl:value-of select="concat('&lt;', $p,':Characteristic', '&gt;')" disable-output-escaping="yes"/> 
    <xsl:apply-templates select="feature:Characteristics"/> 
    <xsl:value-of select="concat('&lt;/', $p,':Characteristic', '&gt;')" disable-output-escaping="yes"/> 
    <xsl:copy-of select="*[not(self::feature:Characteristics)]" /> 
</xsl:copy> 
</xsl:template> 
    <xsl:template match="feature:Characteristics"> 
    <arrays:unsignedShort 
     xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays"> 
    <xsl:value-of select="." /> 
    </arrays:unsignedShort> 
</xsl:template> 
</xsl:stylesheet> 
+0

Ça marche! Merci! – evilfred

Questions connexes