Developpez.com

XML

Choisissez la catégorie, puis la rubrique :

logo
Sommaire > Le 'XML Stylesheet Language : Transformations' (XSLT) > Feuilles XSLT > Opération sur les arbres
        Comparaison ordonnée de deux documents XML
        Comparaison non ordonnée
        Profondeur d'un arbre
        Répartition par profondeur des feuilles



Auteur : Erwan Amoureux
Version : 06/02/2007
Comparaison ordonnée de deux documents XML
Ce code XSLT permet de comparer deux XML, et de vérifier s'ils sont strictement égaux.
Le XSLT

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="C:\Documents and Settings\AMOUREUX\Mes documents\xmlsource\compOrd.xslt"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
	<xsl:template match="/">
		les deux docs sont identiques ?
		<xsl:variable name="doc2">profondeur2.xml</xsl:variable>
		<xsl:variable name="res">
			<xsl:choose>
				<xsl:when test="count(node())=count(document($doc2)/node())">
					<xsl:apply-templates select="/node()">
						<xsl:with-param name="noeuds" select="document($doc2)/node()"/>
					</xsl:apply-templates>
				</xsl:when>
				<xsl:otherwise>
					<xsl:value-of select="1"/>
				</xsl:otherwise>
			</xsl:choose>
		</xsl:variable>
		<xsl:choose>
			<xsl:when test="contains(string($res),'1') ">non </xsl:when>
			<xsl:otherwise>oui</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	<xsl:template match="node()">
		<xsl:param name="noeuds"/>
		<xsl:variable name="pos" select="position()"/>
		<xsl:choose>
			<xsl:when test="count(@*)=count($noeuds[$pos]/@*) and name(.)=name($noeuds[$pos]) and  .=$noeuds[$pos] and  count(node())=count($noeuds[$pos]/node())">
				<xsl:variable name="at">
					<xsl:apply-templates select="@*">
						<xsl:with-param name="noeuds" select="$noeuds[$pos]/@*"/>
					</xsl:apply-templates>
				</xsl:variable>
				<xsl:choose>
					<xsl:when test="not(contains(string($at),'1'))">
						<xsl:apply-templates select="node()">
							<xsl:with-param name="noeuds" select="$noeuds[$pos]/node()"/>
						</xsl:apply-templates>
					</xsl:when>
					<xsl:otherwise>
						<xsl:value-of select="1"/>
					</xsl:otherwise>
				</xsl:choose>
			</xsl:when>
			<xsl:otherwise>
				<xsl:value-of select="1"/>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	<xsl:template match="@*">
		<xsl:param name="noeuds"/>
		<xsl:variable name="pos" select="position()"/>
		<xsl:if test="not(name(.)=name($noeuds[$pos]) and  .=$noeuds[$pos] )">
			<xsl:value-of select="1"/>
		</xsl:if>
	</xsl:template>
</xsl:stylesheet>

Auteur : Erwan Amoureux
Version : 06/02/2007
Comparaison non ordonnée
Ce script est un peu plus complexe car il vérifie sans tenir compte de l'ordre des noeuds.
Le XSLT
<?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" version="1.0" encoding="UTF-8" indent="yes"/>
	<xsl:variable name="doc" select="document('profondeur2.xml')"/>
	<xsl:template match="/">
		les deux docs sont identiques ?
		<xsl:variable name="res">
			<xsl:choose>
				<xsl:when test="count(node())=count($doc/node())">
					<xsl:apply-templates select="/node()">
						<xsl:with-param name="noeuds" select="$doc/node()"/>
					</xsl:apply-templates>
				</xsl:when>
				<xsl:otherwise>
					<xsl:value-of select="1"/>
				</xsl:otherwise>
			</xsl:choose>
		</xsl:variable>
		<xsl:choose>
			<xsl:when test="contains(string($res),'1') ">non </xsl:when>
			<xsl:otherwise>oui</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	<xsl:template match="node()">
		<xsl:param name="noeuds"/>
		<xsl:variable name="Possible" select="$noeuds[count(current()/@*)=count(./@*) and name(current())=name(.)  and  count(current()/node())=count(./node())]"/>
		<xsl:choose>
			<xsl:when test="$Possible">
				<xsl:variable name="Npos">
					<xsl:if test="count(./@*)!=0">
					<xsl:variable name="courant" select="current()"/>
						<xsl:for-each select="$Possible">
						
							<xsl:variable name="at">
								<xsl:for-each select="@*">
									<xsl:if test="not($courant/@* [name(.)=name(current()) and  .=current()])">
										<xsl:value-of select="1"/>
									</xsl:if>
								</xsl:for-each>
								
							</xsl:variable>
							<xsl:if test="not(contains(string($at),'1'))">
								<xsl:value-of select="concat(';',position(),';')"/>
							</xsl:if>
						</xsl:for-each>
					</xsl:if>
				</xsl:variable>
				<xsl:choose>
					<xsl:when test="count(./@*)=0">
						<xsl:apply-templates select="*">
							<xsl:with-param name="noeuds" select="$Possible/*"/>
						</xsl:apply-templates>
						<xsl:apply-templates select="text()">
							<xsl:with-param name="noeuds" select="$Possible/text()"/>
						</xsl:apply-templates>
						<xsl:apply-templates select="comment()">
							<xsl:with-param name="noeuds" select="$Possible/comment()"/>
						</xsl:apply-templates>
					</xsl:when>
					<xsl:when test="contains(string($Npos),';' )">
						<xsl:apply-templates select="*">
							<xsl:with-param name="noeuds" select="$Possible[contains(string($Npos),concat(';',position(),';'))]/*"/>
						</xsl:apply-templates>
						<xsl:apply-templates select="text()">
							<xsl:with-param name="noeuds" select="$Possible[contains(string($Npos),concat(';',position(),';'))]/text()"/>
						</xsl:apply-templates>
						<xsl:apply-templates select="comment()">
							<xsl:with-param name="noeuds" select="$Possible[contains(string($Npos),concat(';',position(),';'))]/comment()"/>
						</xsl:apply-templates>
					</xsl:when>
					<xsl:otherwise>
						<xsl:value-of select="1"/>
					</xsl:otherwise>
				</xsl:choose>
			</xsl:when>
			<xsl:otherwise>
				<xsl:value-of select="1"/>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	<xsl:template match="text()|comment()">
		<xsl:param name="noeuds"/>
		<xsl:if test="not($noeuds[.=current() and name(.)=''])">
			<xsl:value-of select="1"/>
		</xsl:if>
	</xsl:template>
</xsl:stylesheet>

Auteur : Erwan Amoureux
Version : 06/02/2007
Profondeur d'un arbre
Cette information peut-être utile pour avoir une idée de la complexité des données qui sont stockées.
Le XSLT
<?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" version="1.0" encoding="UTF-8" indent="yes"/>
	<xsl:template match="/">
	profondeur : <xsl:call-template name="profondeur">
			<xsl:with-param name="noeud" select="/"/>
		</xsl:call-template>
	</xsl:template>
	<xsl:template name="profondeur">
		<xsl:param name="noeud"/>
		<xsl:param name="prof" select="0"/>
		<xsl:choose>
			<xsl:when test="$noeud/*">
				<xsl:call-template name="profondeur">
					<xsl:with-param name="noeud" select="$noeud/*"/>
					<xsl:with-param name="prof" select="$prof + 1"/>
				</xsl:call-template>
			</xsl:when>
			<xsl:otherwise>
				<xsl:value-of select="$prof"/>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
</xsl:stylesheet>

Auteur : Erwan Amoureux
Version : 06/02/2007
Répartition par profondeur des feuilles
Permet de quantifier la taille de chaque niveau de donnée.
Le XSLT

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
	<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
	<xsl:key name="prof" match="*" use="count(ancestor-or-self::*)"/>
	<xsl:template match="/">
		<res>
			<xsl:call-template name="profondeur">
				<xsl:with-param name="It" select="1"/>
			</xsl:call-template>
		</res>
	</xsl:template>
	<xsl:template name="profondeur">
		<xsl:param name="It"/>
		<xsl:variable name="noeud" select="key('prof',$It)"/>
		<xsl:if test="$noeud">
			<xsl:if test="$noeud[not(*)]">
	Il existe <xsl:value-of select="count($noeud[not(*)])"/> feuille(s) de profondeur <xsl:value-of select="$It"/>
				<br/>
			</xsl:if>
			<xsl:call-template name="profondeur">
				<xsl:with-param name="It" select="$It + 1"/>
			</xsl:call-template>
		</xsl:if>
	</xsl:template>
</xsl:stylesheet>


Consultez les autres pages sources


Valid XHTML 1.0 TransitionalValid CSS!

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2006 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Contacter le responsable de la rubrique XML