Вот общий способ избавиться от выражений document('')/*/someName
:
Исходное преобразование обрабатывается специальным преобразованием, которое генерирует эквивалентное преобразование, которое не содержит вызова функции document('')
.
Тогда вам просто нужно использовать сгенерированное преобразование.
Пример :
Это преобразование (назовем его tA
), содержащее document('')
:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my" >
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:paramDoc1>
<x>123</x>
<y>37</y>
</my:paramDoc1>
<my:paramDoc2>
<x>456</x>
<y>79</y>
</my:paramDoc2>
<xsl:variable name="vpDoc1" select="document('')/*/my:paramDoc1"/>
<xsl:variable name="vpDoc2" select="document('')/*/my:paramDoc2"/>
<xsl:template match="/*">
<xsl:value-of select="$vpDoc1/x"/>
<xsl:text>|</xsl:text>
<xsl:value-of select="$vpDoc2/y"/>
</xsl:template>
</xsl:stylesheet>
при применении к любому документу создает :
123|79
Теперь мы обрабатываем приведенное выше преобразование с этим (tGen
) :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="a:a" exclude-result-prefixes="x">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:namespace-alias stylesheet-prefix="x"
result-prefix="xsl"/>
<xsl:variable name="vApos">'</xsl:variable>
<xsl:variable name="vSelectPrefix" select=
"concat('document(', $vApos,$vApos, ')/*/')"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="xsl:stylesheet">
<x:stylesheet xmlns:ext="http://exslt.org/common">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</x:stylesheet>
</xsl:template>
<xsl:template match="xsl:variable">
<xsl:variable name="vSelattr" select="@select"/>
<xsl:choose>
<xsl:when test="not(starts-with(@select, $vSelectPrefix))">
<xsl:call-template name="identity"/>
</xsl:when>
<xsl:otherwise>
<x:variable name="vrtf{@name}">
<xsl:copy-of select=
"/*/*[name()
= substring-after($vSelattr, $vSelectPrefix)
]"/>
</x:variable>
<x:variable name="{@name}" select=
"ext:node-set($vrtf{@name})/*"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Результатом является новое преобразование (tRes
), которое не содержит выражений типа document('')
:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common">
<xsl:output omit-xml-declaration="yes"
indent="yes" xmlns:my="my:my" />
<xsl:strip-space elements="*" xmlns:my="my:my" />
<my:paramDoc1 xmlns:my="my:my">
<x>123</x>
<y>37</y>
</my:paramDoc1>
<my:paramDoc2 xmlns:my="my:my">
<x>456</x>
<y>79</y>
</my:paramDoc2>
<xsl:variable name="vrtfvpDoc1">
<my:paramDoc1 xmlns:my="my:my">
<x>123</x>
<y>37</y>
</my:paramDoc1>
</xsl:variable>
<xsl:variable name="vpDoc1" select="ext:node-set($vrtfvpDoc1)/*" />
<xsl:variable name="vrtfvpDoc2">
<my:paramDoc2 xmlns:my="my:my">
<x>456</x>
<y>79</y>
</my:paramDoc2>
</xsl:variable>
<xsl:variable name="vpDoc2" select="ext:node-set($vrtfvpDoc2)/*" />
<xsl:template match="/*" xmlns:my="my:my">
<xsl:value-of select="$vpDoc1/x" />
<xsl:text>|</xsl:text>
<xsl:value-of select="$vpDoc2/y" />
</xsl:template>
</xsl:stylesheet>
Если мы теперь применим это динамически сгенерированное преобразование (tRes
) к любому документу XML, результат будет точно таким же , что и при применении исходного преобразования (tA
) к этому документу:
123|79
Следовательно, мы можем использовать tGen
для преобразования преобразования, содержащего выражения document('')
, в эквивалентное преобразование, которое не содержит таких выражений .