这是我的要求:
Lastname是用户名,如果lastname相同则使用lastname + First initial,如果lastname + First initial相同则使用lastname + First initial + second letter first name。
我尝试使用密钥但我没有成功。(输入是一个包含人口统计数据的XML文档,总共可能有大约1200条记录,需要比较此XML文件中的姓氏并根据条件生成用户名如上所述)。 这是我的第一个问题,请让我知道你需要回答的信息。
我可以使用XSLT 1.0或2.0
以下是XML示例:
<XML>
<Data>
<First_Name>Chris</First_Name>
<Middle_Name>E</Middle_Name>
<Last_Name>Kyle</Last_Name>
<Employee_ID>100</Employee_ID>
</Data>
<Data>
<First_Name>Allen</First_Name>
<Middle_Name></Middle_Name>
<Last_Name>Kyle</Last_Name>
<Employee_ID>101</Employee_ID>
</Data>
<Data>
<First_Name>Aron</First_Name>
<Middle_Name></Middle_Name>
<Last_Name>Kyle</Last_Name>
<Employee_ID>102</Employee_ID>
</Data>
<Data>
<First_Name>Luffy</First_Name>
<Middle_Name>D</Middle_Name>
<Last_Name>Monkey</Last_Name>
<Employee_ID>103</Employee_ID>
</Data>
<XML>
对于转换后的这个例子,我应该得到如下的用户名: 1)Kylec 2)Kyleal 3)Kylear 4)猴
这是我的部分工作的XSLT(有多个更改,但目前卡在这里)
<xsl:template match="/">
<xsl:call-template name="HeaderRecord"/>
<xsl:for-each select="//XML/Data[generate-id(.)= generate-id(key('ELN',Last_Name)[1])]">
<xsl:sort select="Last_Name" order="ascending"/>
<xsl:for-each select="key('ELN',Last_Name)">
<xsl:if test="position()=0">
<xsl:call-template name="DataRecords"/>
</xsl:if>
<xsl:if test="position()=1">
<xsl:for-each select="//XML/Data[generate-id(.)= generate-id(key('EFN1',substring(First_Name,1,1))[1])]">
<xsl:for-each select="key('EFN1',substring(First_Name,1,1))">
<xsl:sort select="First_Name" order="ascending"/>
<xsl:if test="position()=0">
<xsl:call-template name="DuplicateDataRecords"/>
</xsl:if>
<xsl:if test="position()=1">
<xsl:call-template name="DuplicateDataRecords2"/>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
谢谢!
答案 0 :(得分:1)
您可以在检查现有名称时为每个条件定义单独的键;仅适用于Last_Name
,Last_Name
加First_Name
的第一个字母,Last_Name
的abd加上First_Name
的前两个字母
<xsl:key name="ELN" match="Data" use="Last_Name" />
<xsl:key name="EFN1" match="Data" use="concat(Last_Name, substring(First_Name,1,1))" />
<xsl:key name="EFN2" match="Data" use="concat(Last_Name, substring(First_Name,1,2))" />
然后,你可以有一个匹配Data
的模板,其中有xsl:choose
依次使用键测试所有条件。
因此,要检查这是Last_Name
的第一次出现(并使用姓氏作为用户名),请执行此操作
<xsl:when
test="generate-id(.)= generate-id(key('ELN',Last_Name)[1])">
下一个xsl:when
将测试Last_Name
+ First_Name
的第一个字符,但它还必须检查此组合在任何地方都不是有效Last_Name
。
<xsl:when
test="generate-id(.)= generate-id(key('EFN1',concat(Last_Name, substring(First_Name,1,1)))[1])
and not(key('ELN', concat(Last_Name, substring(First_Name,1,1))))">
同样,检查First_Name
<xsl:when
test="generate-id(.)= generate-id(key('EFN2',concat(Last_Name, substring(First_Name,1,2)))[1])
and not(key('EFN1', concat(Last_Name, substring(First_Name,1,2))))
and not(key('ELN', concat(Last_Name, substring(First_Name,1,2))))">
试试这个XSLT ......
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:key name="ELN" match="Data" use="Last_Name" />
<xsl:key name="EFN1" match="Data" use="concat(Last_Name, substring(First_Name,1,1))" />
<xsl:key name="EFN2" match="Data" use="concat(Last_Name, substring(First_Name,1,2))" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Data">
<User_Name>
<xsl:choose>
<xsl:when test="generate-id(.)= generate-id(key('ELN',Last_Name)[1])">
<xsl:value-of select="Last_Name" />
</xsl:when>
<xsl:when test="generate-id(.)= generate-id(key('EFN1',concat(Last_Name, substring(First_Name,1,1)))[1])
and not(key('ELN', concat(Last_Name, substring(First_Name,1,1))))">
<xsl:value-of select="concat(Last_Name, substring(First_Name,1,1))" />
</xsl:when>
<xsl:when test="generate-id(.)= generate-id(key('EFN2',concat(Last_Name, substring(First_Name,1,2)))[1])
and not(key('EFN1', concat(Last_Name, substring(First_Name,1,2))))
and not(key('ELN', concat(Last_Name, substring(First_Name,1,2))))">
<xsl:value-of select="concat(Last_Name, substring(First_Name,1,2))" />
</xsl:when>
<xsl:otherwise>
<xsl:variable name="username" select="concat(Last_Name, substring(First_Name,1,2))" />
<xsl:value-of select="$username" />
<xsl:value-of select="count(preceding-sibling::Data[concat(Last_Name, substring(First_Name,1,2)) = $username]) + 1" />
</xsl:otherwise>
</xsl:choose>
</User_Name>
</xsl:template>
</xsl:stylesheet>
请注意,如果Last_Name
+ First_Name
的前两个字母不是唯一的,我使用的后退是在用户名的末尾附加一个数字。