你好
我需要以下xml
<Data>
<Employees>
<Employee>
<EmployeeName>Ram</EmployeeName>
<EmployeeID>123</EmployeeID>
<Gender>M</Gender>
</Employee>
<Employee>
<EmployeeName>Helen</EmployeeName>
<EmployeeID>432</EmployeeID>
<Gender>F</Gender>
</Employee>
<Employee>
<EmployeeName>Dinesh</EmployeeName>
<EmployeeID>321</EmployeeID>
<Gender>M</Gender>
</Employee>
</Employees>
</Data>
转换为此
<?xml version="1.0" encoding="UTF-8"?>
<Employees>
<Employee Gender="Male" Current="true" index="1">
<Name>Ram</Name>
</Employee>
<Employee Gender="Male" Current="false" index="2">
<Name>Dinesh</Name>
</Employee>
<Employee Gender="Female" Current="false" index="3">
<Name>Helen</Name>
</Employee>
</Employees>
我使用的样式表就是这个
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="Data">
<Employees>
<xsl:for-each select="Employees/Employee[Gender = 'M']">
<Employee Gender="Male">
<Name>
<xsl:value-of select="EmployeeName"/>
</Name>
</Employee>
</xsl:for-each>
<xsl:for-each select="Employees/Employee[Gender = 'F']">
<Employee Gender="Female">
<Name>
<xsl:value-of select="EmployeeName"/>
</Name>
</Employee>
</xsl:for-each>
</Employees>
</xsl:template>
</xsl:stylesheet>
我尝试使用过几个样本,但是没什么好看的。请问有人帮我吗?这只是我用来解释问题的示例代码。
或者更具体,
仅需要在第一个员工节点中设置“当前”。另一方面,索引应该在所有节点上。
答案 0 :(得分:2)
您可以使用position()
来确定元素在其父元素下的位置。我也倾向于重构模板以支持apply-templates
,并为男性和女性干掉重复的员工映射。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="Data">
<Employees>
<xsl:apply-templates select="Employees/Employee">
<xsl:sort select="Gender" order="descending" />
</xsl:apply-templates>
</Employees>
</xsl:template>
<xsl:template match="Employee">
<xsl:variable name="gender">
<xsl:choose>
<xsl:when test="Gender='M'">Male</xsl:when>
<xsl:when test="Gender='F'">Female</xsl:when>
<xsl:otherwise>Unknown</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="current">
<xsl:choose>
<xsl:when test="position() = 1">true</xsl:when>
<xsl:otherwise>false</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<Employee Gender="{$gender}" Current="{$current}" index="{position()}">
<Name>
<xsl:value-of select="EmployeeName"/>
</Name>
</Employee>
</xsl:template>
</xsl:stylesheet>
编辑根据@Ians解决方案,我添加了排序和Current
属性。然而,我不确定复杂情况是什么 - 或许我错过了其他的东西?
答案 1 :(得分:1)
我只使用一个for-each
(或者更可能是apply-templates
,但我会按照您当前的结构进行操作),这样您就可以使用position()
来生成索引。为了使所有Male
员工首先加上Female
员工,<xsl:sort>
for-each
按Gender
的降序排列就足够了(因为“M”后来在字母表中而不是“F”):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="Data">
<Employees>
<xsl:for-each select="Employees/Employee">
<xsl:sort select="Gender" order="descending" />
<Employee Gender="{Gender}" index="{position()}">
<xsl:attribute name="Current">
<xsl:choose>
<xsl:when test="position() = 1">true</xsl:when>
<xsl:otherwise>false</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<Name>
<xsl:value-of select="EmployeeName"/>
</Name>
</Employee>
</xsl:for-each>
</Employees>
</xsl:template>
</xsl:stylesheet>