首先我使用xslt 1.0。
我有一些结构:
<Users>
<User name="Alex" surname="Jones"/>
<User name="Mary" surname="Jones"/>
<User name="Jane" surname="Wolf"/>
<User name="John" />
</Users>
现在我需要从中做出。
<Families>
<Family surname="Jones">
<Name>Alex</Name>
<Name>Mary</Name>
</Family>
<Family surname="Wolf">
<Name>Jane</Name>
</Family>
<Family surname="No surname">
<Name>John</Name>
</Family>
</Families>
当我使用<xslt:key...>
时,它只显示有姓氏的用户。
答案 0 :(得分:3)
您不能将空字符串用作非值作为键的值。尝试类似:
XSLT 1.0
<?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:key name="user-by-surname" match="User" use="@surname" />
<xsl:template match="/Users">
<Families>
<xsl:for-each select="User[generate-id()=generate-id(key('user-by-surname', @surname)[1])]">
<Family surname="{@surname}">
<xsl:apply-templates select="key('user-by-surname', @surname)"/>
</Family>
</xsl:for-each>
<xsl:if test="User[not(@surname)]">
<Family surname="no surname">
<xsl:apply-templates select="User[not(@surname)]"/>
</Family>
</xsl:if>
</Families>
</xsl:template>
<xsl:template match="User">
<Name><xsl:value-of select="@name"/></Name>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:2)
此处的替代方案是使用空字符串作为不具有surname
属性的元素的键值的示例:
<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:key name="user-by-surname" match="User" use="string(@surname)" />
<xsl:template match="/Users">
<Families>
<xsl:apply-templates select="User[generate-id()=generate-id(key('user-by-surname', string(@surname))[1])]"/>
</Families>
</xsl:template>
<xsl:template match="User[string(@surname) = '']">
<Family surname="No surname">
<xsl:apply-templates select="key('user-by-surname', string(@surname))" mode="item"/>
</Family>
</xsl:template>
<xsl:template match="User">
<Family surname="{@surname}">
<xsl:apply-templates select="key('user-by-surname', string(@surname))" mode="item"/>
</Family>
</xsl:template>
<xsl:template match="User" mode="item">
<Name>
<xsl:value-of select="@name"/>
</Name>
</xsl:template>
</xsl:stylesheet>