Шаблон заказа не имеет значения. Единственный случай, когда он может быть рассмотрен (и это зависит от процессора), - это когда у вас есть неразрешимый конфликт, то есть состояние ошибки. В этом случае для XSLT-процессора разрешается восстанавливаться после ошибки, выбирая последнюю. Однако вы никогда не должны писать код, который зависит от этого поведения.
В вашем случае приоритет шаблона даже не проблема. У вас есть два разных правила шаблона, одно из которых соответствует <medication>
элементам, а другое соответствует <name>
элементам. Они никогда не столкнутся, поэтому речь не идет о приоритете шаблона или переопределении. Проблема в том, что ваш код никогда не применяет шаблоны к элементу <name>
. Когда вы говорите <xsl:copy-of select="."/>
на <medication>
, вы говорите: «выполнить глубокую копию <medication>
». Единственный способ, которым любое из правил шаблона будет срабатывать для узлов-потомков, - это если вы явно применяете шаблоны (используя <xsl:apply-templates/>
.
Решение, которое я имею для вас, в основном такое же, как у alamar, за исключением того, что оно использует отдельный «режим» обработки, который изолирует правила от всех других правил в вашей таблице стилей. Общий шаблон match="@* | node()"
вызывает рекурсивное применение правил шаблона к дочерним элементам (и атрибутам), что дает вам возможность переопределить поведение для определенных узлов.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- ...placeholder for the rest of your code... -->
<xsl:template match="/record">
<record>
<xsl:apply-templates/>
</record>
</xsl:template>
<!-- end of placeholder -->
<xsl:template match="medication">
<!-- Instead of copy-of, whose behavior is to always perform
a deep copy and cannot be customized, define your own
processing mode. Rules with this mode name are isolated
from the rest of your code. -->
<xsl:apply-templates mode="copy-medication" select="."/>
</xsl:template>
<!-- By default, copy all nodes and their descendants -->
<xsl:template mode="copy-medication" match="@* | node()">
<xsl:copy>
<xsl:apply-templates mode="copy-medication" select="@* | node()"/>
</xsl:copy>
</xsl:template>
<!-- But replace <name> -->
<xsl:template mode="copy-medication" match="medicine/name">
<text>!unauthorized information!</text>
</xsl:template>
</xsl:stylesheet>
Правило для "medicine/name
" переопределяет правило для "@* | node()
", потому что формат шаблона (который содержит "/
") делает его приоритет по умолчанию (0,5) выше, чем приоритет по умолчанию "node()
" (-1,0).
Полное, но краткое описание того, как работает приоритет шаблона, можно найти в «Как работает XSLT» на моем веб-сайте.
Наконец, я заметил, что вы упомянули, что хотите отобразить «RAW XML» для пользователя. Означает ли это, что вы хотите отобразить, например, XML со всеми начальными и конечными тегами в браузере? В этом случае вам нужно будет избежать разметки (например, "<
" для "<
"). Проверьте утилиту XML-to-string на моем веб-сайте. Дайте мне знать, если вам нужен пример того, как его использовать.