2010-09-06 4 views
7

J'essaie de transformer un fichier XML avec l'espace de noms suivant, mais je n'ai pas trouvé de moyen de le faire fonctionner avec l'espace de noms par défaut sans ajouter de préfixe au fichier XML de sortie.XSLT transforme XML avec l'espace de noms par défaut sans ajouter de préfixe?

fichier XML d'origine:

<pExport xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://workflow.converga.com.au/compass"> 

je peux le faire fonctionner en ajoutant un préfixe à l'espace de noms par défaut (le dernier), mais comment pourrais-je sortir un XML sans ajouter un préfixe, il est possible par utilisant XslCompiledTransform dans .NET 4?

+0

Vous semblez dire que vous ne pouvez * pas * trouver un moyen de le faire fonctionner avec l'espace de noms par défaut sans ajouter de préfixe au fichier XML de sortie. En quoi cela ne fonctionne-t-il pas? Quel est le comportement observé lorsque vous n'ajoutez pas de préfixe? Vous avez étiqueté ceci avec XSLT, alors peut-être voulez-vous dire qu'un processeur XSLT ne reconnaît pas l'élément pExport dans l'espace de noms workflow/compass? Plus d'informations sont nécessaires. Cela pourrait aider à montrer la partie pertinente de votre feuille de style. – LarsH

+0

Bonne question (+1).Voir ma réponse pour un exemple concret et la solution utilisée. –

+0

LarsH, oui ce que je voulais dire, c'est que sans ajouter de préfixe, la sortie XSLT ne serait pas capable de faire correspondre les nœuds avec l'espace de nom par défaut (sans tag). Je cherche un moyen de faire correspondre ces éléments sans ajouter mon propre préfixe pour l'espace de noms par défaut. –

Répondre

4

je peux le faire fonctionner en ajoutant un préfixe à l'espace de noms par défaut (le dernier), mais comment pourrais-je sortir un XML sans ajouter un préfixe, il est possible en utilisant XslCompiledTransform dans. NET 4?

Voici un exemple concret comment faire:

Cette transformation:

<xsl:stylesheet version="1.0" 
xmlns="http://workflow.converga.com.au/compass" 
xmlns:c="http://workflow.converga.com.au/compass" 
xmlns:ext="http://exslt.org/common" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
exclude-result-prefixes="c ext xsl"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:param name="pnewItem"> 
    <item name="wine"> 
    <price>3</price> 
    <quantity>5000</quantity> 
    </item> 
</xsl:param> 

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

<xsl:template match="c:item[last()]"> 
    <xsl:call-template name="identity"/> 
    <xsl:copy-of select="ext:node-set($pnewItem)/*"/> 
</xsl:template> 
</xsl:stylesheet> 

lorsqu'il est appliqué avec XslCompiledTransform sur le document XML suivant:

<pExport xmlns="http://workflow.converga.com.au/compass"> 
<Goods> 
    <item name="tobacco"> 
    <price>5</price> 
    <quantity>1000</quantity> 
    </item> 
</Goods> 
</pExport> 

produit le voulait (le même document XML avec un nouvel élément ajouté), résultat correct:

<pExport xmlns="http://workflow.converga.com.au/compass"> 
    <Goods> 
    <item name="tobacco"> 
     <price>5</price> 
     <quantity>1000</quantity> 
    </item> 
    <item name="wine"> 
     <price>3</price> 
     <quantity>5000</quantity> 
    </item> 
    </Goods> 
</pExport> 
+0

Merci, en suivant votre exemple, je l'ai fait fonctionner en ajoutant un espace de noms par défaut sans préfixe et des options "exclude-result-prefixex". En fait, je ne comprends pas complètement votre code et comment ils sont supposés fonctionner (juste appris XSLT hier). Par exemple, que font ces sections dans votre premier bloc de code? –

+0

Une chose mineure, dans le XML de sortie, l'espace de noms par défaut est toujours le premier, puis-je changer cela pour le dernier, qui est la position du XML original. –

+0

@pstar: Les spécifications XSLT et XML W3C n'imposent aucun ordre spécifique pour les attributs et les nœuds d'espace de noms. Leur ordre relatif est "dépendant de l'implémentation". Cela signifie que selon le processeur XSLT concret que vous utilisez, vous n'avez aucun contrôle sur l'ordre des déclarations d'espace de noms ou si vous avez un certain contrôle, cette "fonctionnalité" n'est pas portable et n'est pas supportée par les autres processeurs XSLT. –

1

Vous avez simplement besoin de définir votre espace de noms par défaut dans le fichier XSLT. Si vous aussi définir un avec un préfixe ainsi que vous pouvez sélectionner des éléments dans le fichier XML d'entrée avec facilité:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://workflow.converga.com.au/compass" xmlns:compass="http://workflow.converga.com.au/compass"> 
    <xsl:template match="compass:pExport"> 
    <pExport>...</pExport> 
    ... 

Le modèle ci-dessus correspondra contre votre élément XML d'entrée - et l'élément littéral créé sera en défaut espace de noms de sortie (qui est le même espace de noms). Bien sûr, vous devez savoir que le préfixe n'est pas pertinent dans XML: deux éléments sont identiques s'ils ont le même espace de nom et le même nom local, même si les deux préfixes sont définis pour cet espace de noms.

<element xmlns="http://test.com"></element> 
<ns01:element xmlns:ns01="http://test.com"></ns01:element> 

Les deux éléments ci-dessus sont les mêmes car ils ont le même nom complet.

+0

pour copier l'élément correspondant avec le même espace de noms, vous n'avez pas besoin de déclarer un espace de nom par défaut pour la sortie, l'instruction 'copy' fonctionne également de cette manière. –

+0

Je pense que vous avez raison dans le sens que le préfixe ne devrait pas affecter l'espace de noms. Et votre solution fonctionne dans ce sens. Ce que je cherche est une solution sans ajouter mon propre préfixe à l'espace de noms par défaut. –

+0

Le préfixe n'est pas pertinent * en théorie *. En pratique, certains analyseurs syntaxiques ne sont pas compatibles avec les espaces de noms, mais vous souhaitez quand même générer le document avec un rédacteur conforme. De plus, les spécifications de certains standards autonomes basés sur XML n'utilisent pas du tout un espace de nommage. – dolmen

4

La clé est d'utiliser l'attribut exclude-result-prefixes sur l'élément stylesheet.

Il y a quelques bonnes explications dans this section du XSLT FAQ.

+0

MERCI Dolment pour signaler les informations pour moi. En fait, j'ai déjà lu un peu de XSLT, mais je ne l'ai pas trouvé. Devinez la FAQ est un peu trop d'informations pour moi. –

+0

Un bon moyen de remercier pour une réponse est de voter pour cela en cliquant sur la flèche vers le haut sur le côté gauche. Pourrais-tu le faire pour le mien? – dolmen

+0

Voté pour la FAQ XLT. – Fortisimo

Questions connexes