Подход с шаблоном идентификации
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
вполне подходит, теперь для использования вам просто нужно добавить шаблоны для тех элементов, которые вы хотите изменить, например,
<xsl:template match="Body/A">
<xsl:copy>
<xsl:value-of select="ancestor::MaXML/Rule/A"/>
</xsl:copy>
</xsl:template>
https://xsltfiddle.liberty -development.net / pPqsHTK
Должно быть понятно, я надеюсь, как добавить третий шаблон, соответствующий Body/C/D
и выбрав значение из соответствующего Rule
при необходимости.
Если вам нужен универсальный подход, то в XSLT 2 или 3 это просто с помощью клавиши и вызова ключевой функции в поддереве:
<xsl:key name="ref" match="MaXML/Rule/*" use="node-name()"/>
<xsl:template match="Body//*[key('ref', node-name(), ancestor::MaXML)]">
<xsl:copy>
<xsl:value-of select="key('ref', node-name(), ancestor::MaXML)"/>
</xsl:copy>
</xsl:template>
Полный XSLT 3 в https://xsltfiddle.liberty-development.net/pPqsHTK/3 равен
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:key name="ref" match="MaXML/Rule/*" use="node-name()"/>
<xsl:template match="Body//*[key('ref', node-name(), ancestor::MaXML)]">
<xsl:copy>
<xsl:value-of select="key('ref', node-name(), ancestor::MaXML)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
К сожалению, XSLT 1 не имеет третьего аргумента для функции key
, поэтому для реализации общего подхода с ключом вам необходимовключите generate-id(ancestor::MaXML)
в значение ключа:
<xsl:key name="ref" match="MaXML/Rule/*" use="concat(generate-id(ancestor::MaXML), '|', name())"/>
<xsl:template match="Body//*[key('ref', concat(generate-id(ancestor::MaXML), '|', name()))]">
<xsl:copy>
<xsl:value-of select="key('ref', concat(generate-id(ancestor::MaXML), '|', name()))"/>
</xsl:copy>
</xsl:template>
Пример на https://xsltfiddle.liberty -development.net / pPqsHTK / 4 .