web-dev-qa-db-fra.com

Comment supprimer des espaces de noms de XML à l'aide de XSLT

J'ai un fichier XML de 150 Mo (cela peut aller encore plus parfois). J'ai besoin de supprimer tous les espaces de noms. C'est sur Visual Basic 6.0, donc j'utilise DOM pour charger le XML. Le chargement est correct, j'étais sceptique au début, mais d'une manière ou d'une autre, cette partie fonctionne bien.

J'essaye ce qui suit XSLT , mais il supprime également tous les autres attributs. Je veux conserver tous les attributs et éléments, j'ai juste besoin de supprimer les espaces de noms. Apparemment, c'est parce que j'ai xsl:element mais pas d'attribut. Comment puis-je y inclure les attributs?

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="UTF-8" />
    <xsl:template match="*">
        <xsl:element name="{local-name()}">
            <xsl:apply-templates select="@* | node()"/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>
21
GaneshT

Votre XSLT supprime également les attributs, car vous n'avez pas de modèle qui les copierait. <xsl:template match="*"> Ne correspond qu'à des éléments, pas à des attributs (ou du texte, des commentaires ou des instructions de traitement).

Vous trouverez ci-dessous une feuille de style qui supprime toutes les définitions d'espace de noms du document traité mais copie tous les autres nœuds et valeurs: éléments, attributs, commentaires, texte et instructions de traitement. Veuillez faire attention à 2 choses

  1. La copie des attributs en tant que tels ne suffit pas pour supprimer tous les espaces de noms. Un attribut peut également appartenir à un espace de noms, même lorsque l'élément conteneur n'appartient pas à un espace de noms. Par conséquent, des attributs doivent également être créés, comme les éléments. La création d'attributs se fait avec l'élément <xsl:attribute>.
  2. Un document XML valide ne peut pas contenir un élément qui a deux ou plusieurs attributs avec le même nom développé mais les éléments peuvent contenir plusieurs attributs avec le même nom local si les attributs ont des espaces de noms différents. Cela signifie que la suppression du préfixe d'espace de noms de un nom d'attribut provoquera une perte de données s'il y a un élément qui a au moins deux attributs avec le même nom local. Un autre de ces attributs sera supprimé (ou remplacé).

... et le code:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output indent="yes" method="xml" encoding="utf-8" omit-xml-declaration="yes"/>

    <!-- Stylesheet to remove all namespaces from a document -->
    <!-- NOTE: this will lead to attribute name clash, if an element contains
        two attributes with same local name but different namespace prefix -->
    <!-- Nodes that cannot have a namespace are copied as such -->

    <!-- template to copy elements -->
    <xsl:template match="*">
        <xsl:element name="{local-name()}">
            <xsl:apply-templates select="@* | node()"/>
        </xsl:element>
    </xsl:template>

    <!-- template to copy attributes -->
    <xsl:template match="@*">
        <xsl:attribute name="{local-name()}">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>

    <!-- template to copy the rest of the nodes -->
    <xsl:template match="comment() | text() | processing-instruction()">
        <xsl:copy/>
    </xsl:template>

</xsl:stylesheet>

Vous pouvez également utiliser <xsl:template match="node()"> au lieu de ce dernier modèle, mais vous devez alors utiliser l'attribut priority pour empêcher les éléments de correspondre à ce modèle.

33
jasso

Comment puis-je y inclure les attributs?

Ajoutez simplement ce modèle à celui que vous avez déjà:

<xsl:template match="@*">
    <xsl:copy/>
</xsl:template>
1
Emiliano Poggi