почему предыдущий код выводит TEXT, почему я должен настаивать на том, чтобы XSL игнорировал весь другой текст?является то, что поведение всех синтаксических анализаторов XML или только мой
Вы обнаруживаете одну из самых фундаментальных функций XSLT, как указано в Спецификации: встроенные шаблоныXSLT .
С Спецификация :
Существует встроенное правило шаблона, позволяющее рекурсивнообработка для продолжения при отсутствии успешного сопоставления с образцом с помощью явного правила шаблона в таблице стилей.Это шаблонное правило применяется как к узлам элемента, так и к корневому узлу.Ниже показан эквивалент встроенного правила шаблона:
<xsl:template match="*|/">
<xsl:apply-templates/>
</xsl:template>
Существует также встроенное правило шаблона для каждого режима, которое позволяет рекурсивной обработке продолжаться в том же режиме при отсутствииуспешное сопоставление с образцом по явному шаблонному правилу в таблице стилей.Это шаблонное правило применяется как к узлам элемента, так и к корневому узлу.Ниже показан эквивалент встроенного правила шаблона для режима m.
<xsl:template match="*|/" mode="m">
<xsl:apply-templates mode="m"/>
</xsl:template>
Существует также встроенное правило шаблона для узлов текста и атрибутов, которое копирует текст через:
<xsl:template match="text()|@*">
<xsl:value-of select="."/>
</xsl:template>
Встроенное правило шаблона для обработки инструкций и комментариев ничего не делает.
<xsl:template match="processing-instruction()|comment()"/>
Встроенное правило шаблона для узлов пространства имен также ничего не делает.Нет шаблона, который мог бы соответствовать узлу пространства имен;таким образом, встроенное правило шаблона является единственным правилом шаблона, которое применяется к узлам пространства имен.
Встроенные правила шаблона обрабатываются так, как если бы они были импортированы неявно до таблицы стилей и поэтому имеют более низкий приоритет импорта, чемвсе остальные правила шаблона.Таким образом, автор может переопределить встроенное правило шаблона, включив явное правило шаблона.
Таким образом, сообщаемое поведение является результатом применения встроенных шаблонов - 1-го и2-й из всех трех.
Это хороший шаблон проектирования XSLT для переопределения встроенных шаблонов с вашим собственным, который при каждом вызове выдаст сообщение об ошибке, так что программист сразу узнаетего преобразование «протекает»:
Например , если есть этот документ XML:
<a>
<b>
<c>Don't want to see this</c>
</b>
</a>
, и он обрабатывается этим преобразованием :
<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="a|b">
<xsl:copy>
<xsl:attribute name="name">
<xsl:value-of select="name()"/>
</xsl:attribute>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
результат равен :
<a name="a">
<b name="b">Don't want to see this</b>
</a>
, и программист будет сильно смущен тем, как появился нежелательный текст.
Тем не менее, просто добавив это catch-all template
, вы избежите любой такой путаницы и сразу же обнаружите ошибки :
<xsl:template match="*">
<xsl:message terminate="no">
WARNING: Unmatched element: <xsl:value-of select="name()"/>
</xsl:message>
<xsl:apply-templates/>
</xsl:template>
Теперь, помимо запутанного вывода, программист получаетпредупреждение, объясняющее проблемунемедленно :
WARNING: Unmatched element: c
Позднее добавление Майклом Кейем для XSLT 3.0
В XSLT 3.0 вместо добавления правила для универсального шаблона вы можетеукажите резервное поведение в объявлении xsl:mode
.Например, <xsl:mode on-no-match="shallow-skip"/>
приводит к пропуску всех несоответствующих узлов (включая текстовые узлы), тогда как <xsl:mode on-no-match="fail"/>
обрабатывает несоответствие как ошибку, а <xsl:mode warning-on-no-match="true"/>
приводит к предупреждению.