Retrait des éléments liés à l'aide de XSLT 1.0
Question
Je tente de supprimer des éléments composant à partir du XML ci-dessous qui ont des enfants de fichiers avec l'extension « config ». J'ai réussi à faire cette partie, mais je dois aussi enlever les éléments ComponentRef correspondant qui ont les mêmes « Id » valeurs que ces composants.
<Fragment>
<DirectoryRef Id="MyWebsite">
<Component Id="Comp1">
<File Source="Web.config" />
</Component>
<Component Id="Comp2">
<File Source="Default.aspx" />
</Component>
</DirectoryRef>
</Fragment>
<Fragment>
<ComponentGroup Id="MyWebsite">
<ComponentRef Id="Comp1" />
<ComponentRef Id="Comp2" />
</ComponentGroup>
</Fragment>
Sur la base d'autres réponses, je suis venu avec le XSLT suivante pour supprimer ces éléments constitutifs:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:template match="Component[File[substring(@Source, string-length(@Source)- string-length('config') + 1) = 'config']]" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Malheureusement, cela ne supprime pas les éléments de ComponentRef correspondants (à savoir ceux qui ont les mêmes valeurs « Id »). Le XSLT supprimera le composant avec l'ID « Comp1 » mais pas le ComponentRef avec Id « Comp1 ». Comment puis-je avoir ce type de XSLT 1.0?
La solution
Une approche assez efficace est d'utiliser xsl:key
pour identifier les ID des composants de configuration:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:key name="configComponent"
match="Component[File/@Source[substring(.,
string-length() - string-length('config') + 1) = 'config']]"
use="@Id" />
<xsl:template match="Component[key('configComponent', @Id)]" />
<xsl:template match="ComponentRef[key('configComponent', @Id)]" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Autres conseils
Comment cela? Je l'ai fait un petit changement à votre original pour simplifier les choses aussi bien (il est plus simple de vérifier si les extrémités d'attribut @source avec « config »).
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:template match="Component[substring(@Source, string-length(@Source) - 5) = 'config']" />
<xsl:template match="ComponentRef[//Component[substring(@Source, string-length(@Source) - 5) = 'config']/@Id = @Id]"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
Ceci a un gabarit qui correspond à tout ComponentRef qui a le même attribut d'ID en tant que composant identifié par le modèle précédent. Une chose - la « //Component
» est pas efficace. Vous devriez être en mesure de le remplacer par quelque chose de plus efficace - je ne connais pas votre structure XML