Para empezar, supongo que debido a alguna razón desconocida no se puede utilizar la dirección URL absoluta en el link
como el UID es necesario - esta es la solución más simple y más natural.
En caso de que mi suposición es correcta, entonces:
Esta es una tarea fácil para XSLT.
Como OP quiere que los identificadores generados sean los mismos cuando la transformación se realiza varias veces, no es apropiado utilizar la función generate-id()
.
Esta es una manera sencilla de producir los identificadores estables:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="link[@href]">
<xsl:variable name="vUid">
<xsl:number level="any" count="link[@href]"/>
</xsl:variable>
<a href="{@href}&no_cache={{{$vUid}}}"/>
</xsl:template>
</xsl:stylesheet>
cuando se aplica esta transformación en el siguiente documento XML (sin importar cuántas veces):
<t>
<link href="1.html"/>
<a>
<link href="2.html"/>
<b>
<link href="3.html"/>
<c>
<link href="4.html"/>
</c>
<link href="5.html"/>
</b>
<link href="6.html"/>
<d>
<link href="7.html"/>
</d>
</a>
<link href="8.html"/>
<e>
<link href="9.html"/>
</e>
<link href="10.html"/>
</t>
el resultado deseado, el mismo y correcto se produce cada vez:
<t>
<a href="1.html&no_cache={1}"/>
<a>
<a href="2.html&no_cache={2}"/>
<b>
<a href="3.html&no_cache={3}"/>
<c>
<a href="4.html&no_cache={4}"/>
</c>
<a href="5.html&no_cache={5}"/>
</b>
<a href="6.html&no_cache={6}"/>
<d>
<a href="7.html&no_cache={7}"/>
</d>
</a>
<a href="8.html&no_cache={8}"/>
<e>
<a href="9.html&no_cache={9}"/>
</e>
<a href="10.html&no_cache={10}"/>
</t>
Nota: El uso de <xsl:number>
para producir la identificación.
Si el mismo enlace puede ocurrir varias veces en el documento y necesitamos todas las ocurrencias de utilizar el mismo ID, aquí está la solución para este problema:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kHrefByVal" match="link/@href" use="."/>
<xsl:variable name="vUniqHrefs" select=
"//link/@href
[generate-id()
=
generate-id(key('kHrefByVal',.)[1])
]
"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="link[@href]">
<xsl:variable name="vthisHref" select="@href"/>
<xsl:variable name="vUid">
<xsl:for-each select="$vUniqHrefs">
<xsl:if test=". = $vthisHref">
<xsl:value-of select="position()"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<a href="{@href}&no_cache={{{$vUid}}}"/>
</xsl:template>
</xsl:stylesheet>
cuando se aplica en esta transformación el siguiente documento XML:
<t>
<link href="1.html"/>
<a>
<link href="2.html"/>
<b>
<link href="1.html"/>
<c>
<link href="3.html"/>
</c>
<link href="2.html"/>
</b>
<link href="1.html"/>
<d>
<link href="3.html"/>
</d>
</a>
<link href="4.html"/>
<e>
<link href="2.html"/>
</e>
<link href="4.html"/>
</t>
el resultado deseado, se produce correcta:
<t>
<a href="1.html&no_cache={1}"/>
<a>
<a href="2.html&no_cache={2}"/>
<b>
<a href="1.html&no_cache={1}"/>
<c>
<a href="3.html&no_cache={3}"/>
</c>
<a href="2.html&no_cache={2}"/>
</b>
<a href="1.html&no_cache={1}"/>
<d>
<a href="3.html&no_cache={3}"/>
</d>
</a>
<a href="4.html&no_cache={4}"/>
<e>
<a href="2.html&no_cache={2}"/>
</e>
<a href="4.html&no_cache={4}"/>
</t>
[generate-id()] (http://www.w3schools.com/XSL/func_generateid.asp). – khachik
no encaja en mi caso. generate-id() no genera identificadores únicos si intento procesar este xml varias veces. Quiero tener una identificación única cada vez – Nawa
Buena pregunta, +1. Vea mi respuesta para una solución XSLT completa y corta. :) –