0

你好

我需要下面的 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>

我尝试使用几个示例,但似乎没有任何效果。任何人都可以帮我解决这个问题吗?这只是我为解释问题而整理的示例代码。

或者更具体地说,

“当前”仅需要在第一个员工节点中设置。另一方面,索引应该在所有节点上。

4

2 回答 2

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属性。但是,我不确定并发症是什么-也许我错过了其他东西?

于 2013-11-11T12:19:44.030 回答
1

我会用一个for-each(或者更有可能apply-templates,但我会遵循你当前的结构)来做,这样你就可以用它position()来生成索引。为了将所有Male员工排在最前面,然后按降序排列Female就足够<xsl:sort>了(因为“M”在字母表中比“F”晚):for-eachGender

<?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>
于 2013-11-11T12:10:16.163 回答