Когда вы используете <xsl:apply-templates/>
, оно действительно короткое для <xsl:apply-templates select="node()"/>
и вызывается внутри совпадения шаблона на /
, который является корневым узлом документа и абстрактной концепцией для верхней части файла. , Это дочерние элементы, включающие элемент документа (т.е. <Page>
), а также любые комментарии верхнего уровня или инструкции по обработке, которые могут быть родственными элементами элемента документа.
Таким образом, когда вы «стоите» на корневом узле, вызов <xsl:apply-templates/>
будет применять шаблоны к /Page
, что соответствует определенному вами шаблону. position()
оценивается из сопоставленный контекст, который равен /Page
и возвращает 2
, потому что это второй элемент в документе. Первый элемент - это инструкция по обработке таблицы стилей xml. Если вы удалите его, то position()
будет равно 1
.
Когда вы используете <xsl:call-template name="PageCount"/>
, он вызывает тот же шаблон, но контекст не изменяется при вызове шаблона. Вы все еще «стоите» на корневом узле, поэтому position()
оценивает до 1
.
count()
всегда оценивает одно и то же, независимо от контекста, потому что он использует XPath, который запускается в корневом узле. Если бы вы изменили его на count(Page/Page)
и оценили относительное значение из узла контекста, вы бы получили разные значения (2
и 5
соответственно).