我正在尝试将唯一的XML子元素值添加到选择列表中。这是我到目前为止所拥有的
XML:
<Student>
<record>
<Name>Jack</Name>
</record>
<record>
<Name>Jack</Name>
</record>
<record>
<Name>John</Name>
</record>
<record>
<Name>John</Name>
</record>
<record>
<Name>John</Name>
</record>
<record>
<Name>Jill</Name>
</record>
<record>
<Name>Jill</Name>
</record>
<record>
<Name>James</Name>
</record>
</Student>
XSLT:
<xsl:key name="NameKey" match="Name" use="."/>
<xsl:template match="Student">
<table>
<tr>
<th>Name</th>
<td>
<select>
<xsl:for-each select="record">
<option>
<xsl:element name="Name">
<xsl:value-of select="Name[generate-id() = generate-id(key('NameKey',.)[1])]" />
</xsl:element>
</option>
</xsl:for-each>
</select>
</td>
</tr>
<xsl:apply-templates select="/record" />
</table>
</xsl:template>
</xsl:stylesheet>
我在列表中成功获取了唯一值,但该列表还为列表中的非唯一值显示空字符串。所以我的列表有以下值:
Jack
John
Jill
James
有没有办法摆脱列表中的那些空字符串值?
答案 0 :(得分:1)
有没有办法摆脱列表中的那些空字符串值?
是的,只需将带有键查找的谓词移动到xsl:for-each
即可。使用您当前的代码,所有这些节点将被传递到xsl:for-each
,包括重复项。
顺便说一句,这一行
<xsl:apply-templates select="/record" />
不执行任何操作,因为最外层的元素节点不会被称为record
。你的意图是什么?
XSLT样式表
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" encoding="UTF-8" indent="yes" />
<xsl:key name="NameKey" match="Name" use="."/>
<xsl:template match="Student">
<table>
<tr>
<th>Name</th>
<td>
<select>
<xsl:for-each select="record/Name[generate-id() = generate-id(key('NameKey',.)[1])]">
<option>
<xsl:element name="Name">
<xsl:value-of select="." />
</xsl:element>
</option>
</xsl:for-each>
</select>
</td>
</tr>
<xsl:apply-templates select="/record" />
</table>
</xsl:template>
</xsl:stylesheet>
HTML输出
<table>
<tr>
<th>Name</th>
<td>
<select>
<option>
<Name>Jack</Name>
</option>
<option>
<Name>John</Name>
</option>
<option>
<Name>Jill</Name>
</option>
<option>
<Name>James</Name>
</option>
</select>
</td>
</tr>
</table>
呈现HTML
答案 1 :(得分:1)
我想补充一点,这也可以通过使用[not(.=preceding::*)]
来实现。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" encoding="UTF-8" indent="yes" />
<xsl:template match="Student">
<table>
<tr>
<th>Name</th>
<td>
<select>
<xsl:for-each select="record/Name[not(.=preceding::*)]">
<option>
<xsl:element name="Name">
<xsl:value-of select="." />
</xsl:element>
</option>
</xsl:for-each>
</select>
</td>
</tr>
<xsl:apply-templates select="/record" />
</table>
</xsl:template>
</xsl:stylesheet>
我个人认为这种方式更加清晰,因为您只处理每个Name元素一次。