Используя функцию position() в xslt

<EmployeeDetails>
    <Employee>
        <Name>TEST</Name>
    </Employee>
    <Employee>
        <Name>TEST</Name>
    </Employee>
    <Employee>
        <Name>TEST</Name>
    </Employee>
    <Employee>
        <Name>TEST</Name>
    </Employee>
    <Employee>
        <Name>TEST</Name>
    </Employee>
</EmployeeDetails>

Я попытался использовать xslt, как показано ниже:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
    exclude-result-prefixes="xd"
    version="1.0">

    <xsl:template match="EmployeeDetails/Employee">
        <xsl:copy>
        <xsl:attribute name="id"><xsl:value-of select="position()"/></xsl:attribute>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*">
        <xsl:element name="{local-name()}">
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="@*">
        <xsl:attribute name="{local-name()}">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>
</xsl:stylesheet>

Для выше xslt вывод для позиции() печатается как 2,4,6,8,10.

и вывод должен быть:

<EmployeeDetails>
    <Employee id="1">
        <Name>TEST</Name>
    </Employee>
    <Employee id="2">
        <Name>TEST</Name>
    </Employee>
    <Employee id="3">
        <Name>TEST</Name>
    </Employee>
    <Employee id="4">
        <Name>TEST</Name>
    </Employee>
    <Employee id="5">
        <Name>TEST</Name>
    </Employee>
</EmployeeDetails>

Как печатать как последовательность, например, 1,2,3.... для атрибута id.

Ответ 1

Команда xsl:number была сделана именно для этой задачи:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="Employee">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:attribute name="id">
                <xsl:number/>
            </xsl:attribute>
            <xsl:apply-templates select="node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*">
        <xsl:element name="{local-name()}">
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="@*">
        <xsl:attribute name="{local-name()}">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>
</xsl:stylesheet>

Вывод:

<EmployeeDetails>
    <Employee id="1">
        <Name>TEST</Name>
    </Employee>
    <Employee id="2">
        <Name>TEST</Name>
    </Employee>
    <Employee id="3">
        <Name>TEST</Name>
    </Employee>
    <Employee id="4">
        <Name>TEST</Name>
    </Employee>
    <Employee id="5">
        <Name>TEST</Name>
    </Employee>
</EmployeeDetails>

Ответ 2

Перед первым <xsl:template> добавьте

<xsl:strip-space elements="*"/> 

Это избавит вас от текстовых узлов с пробелом, на которые ссылается @khachik. Тогда ваша позиция должна быть тем, что вы ожидаете.

Ответ 3

Этот шаблон генерирует то, что вам нужно:

<xsl:template match="EmployeeDetails/Employee">
    <xsl:copy>
        <xsl:attribute name="id">
          <xsl:value-of select="count(preceding-sibling::Employee) + 1"/>
        </xsl:attribute>
    </xsl:copy>
</xsl:template>

Исходная информация.