将唯一的 XML 元素值添加到 select 列表
Add unique XML Element values to a select list
我正在尝试将唯一的 XML 子元素值添加到 select 列表中。这是我目前所拥有的
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
有什么办法可以去掉列表中的那些空字符串值吗?
Is there any way to getting rid of those empty string values in the list?
是的,只需将带有键查找的谓词移动到 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
我想补充一点,这也可以通过使用 [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 元素一次。
我正在尝试将唯一的 XML 子元素值添加到 select 列表中。这是我目前所拥有的
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
有什么办法可以去掉列表中的那些空字符串值吗?
Is there any way to getting rid of those empty string values in the list?
是的,只需将带有键查找的谓词移动到 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
我想补充一点,这也可以通过使用 [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 元素一次。