Шаблон у вас в порядке, и делает свое дело. Проблема в том, что, когда XSLT начинает обработку, он ищет шаблон, соответствующий элементу документа /
, которого нет в вашем шаблоне. Когда XSLT ищет шаблон, и в вашем шаблоне его нет, он использует встроенные шаблоны .
По сути, он будет перемещаться по всему XML и выводить текстовые узлы, где он его найдет. Таким образом, вы получаете много текстового вывода, прежде чем он, наконец, дойдет до вашего шаблона, соответствующего type
.
Есть несколько решений. Одним из них является наличие шаблона, соответствующего /
, и явное выделение type
узлов
<xsl:template match="/">
<xsl:apply-templates select="//type" />
</xsl:template>
Другой вариант - иметь шаблон, соответствующий узлам text()
, чтобы игнорировать их, переопределяя поведение шаблона по умолчанию
<xsl:template match="text()" />
Однако, так как вы используете XSLT 3.0, вы также можете сделать это вместо добавления нового шаблона, чтобы указать действие, которое нужно выполнить для не соответствующего шаблона
<xsl:mode on-no-match="shallow-skip"/>
Обратите внимание, что во всех случаях вам потребуется выводить разрыв строки в существующем шаблоне.
Попробуйте это XSLT
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
<xsl:mode on-no-match="shallow-skip"/>
<xsl:template match="type">
<xsl:value-of select="ancestor::global/attr,
ancestor::employee/details/name,
ancestor::employee/details/age,
@code,
@count"
separator=";" />
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>