我刚开始学习 XSLT,在忽略重复元素时遇到了麻烦。
我一直在搜索 Stack Overflow,看到有人问过类似的问题。我尝试了一个小例子来查看我的文件哪里出了问题,并且能够忽略重复的元素。但是,当我有不止一种类型的元素时,问题似乎就出现了。
例如:
文件1.xml
<?xml-stylesheet type="text/xsl" href="merge2.xsl"?>
<Main>
<Records>
<Record>
<Description>A</Description>
</Record>
<Record>
<Description>A</Description>
</Record>
<Record>
<Description>B</Description>
</Record>
<Record>
<Description>C</Description>
</Record>
</Records>
</Main>
merge2.xsl
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/Transform">
<xsl:output method="html"/>
<xsl:template match="/">
<table border="1">
<tr>
<th>Type</th>
<th>Count</th>
</tr>
<xsl:for-each select="Main/Records/Record">
<xsl:if test ="not(preceding-sibling::Record(Description/text() = current()/Description/text()])">
<tr>
<td><xsl:value-of select="Description"/></td>
<td><xsl:value-of select="count(//Record[Description/text()=current()/Description/text()])"/></td>
</tr>
</xsl:if>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
这很好用,给了我想要的结果。
Type Count
A 2
B 1
C 1
但是,如果我要添加另一个 Records 元素,它似乎会一个接一个地处理这两个元素,例如
<?xml-stylesheet type="text/xsl" href="merge2.xsl"?>
<Main>
<Records>
<Record>
<Description>A</Description>
</Record>
<Record>
<Description>A</Description>
</Record>
<Record>
<Description>B</Description>
</Record>
<Record>
<Description>C</Description>
</Record>
</Records>
<Records>
<Record>
<Description>B</Description>
</Record>
<Record>
<Description>A</Description>
</Record>
<Record>
<Description>C</Description>
</Record>
<Record>
<Description>C</Description>
</Record>
</Records>
</Main>
这将产生以下结果。
Type Count
A 3
B 2
C 3
B 2
A 3
C 3
它似乎处理记录的第一个实例,然后转到下一个。有什么方法可以消除两者之间的重复项吗?
我已经尝试更改 for-each 以遍历记录的每个实例,并尝试为其创建一个单独的模板,但是我似乎仍然遗漏了一些东西,因为我没有设法让它工作。
非常感谢您的帮助。
最佳答案
尝试在 xsl:if 语句
中将 preceding-sibling
替换为 preceding
。
您设计测试的想法是正确的,这样您每次遇到 Description
值时只发出一次 tr
。但是,preceding-sibling
停止通过父级的直接子级进行回溯; preceding
继续检查文档中较早的部分,这是您要避免在 Records
中重复的内容。
仅供引用,还有一个拼写错误,其中 Record(
应该是 Record[
。这是一个完整的操作转换,包括这些更改:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:template match="/">
<table border="1">
<tr>
<th>Type</th>
<th>Count</th>
</tr>
<xsl:for-each select="Main/Records/Record">
<xsl:if test ="not(preceding::Record[Description/text() = current()/Description/text()])">
<tr>
<td><xsl:value-of select="Description"/></td>
<td><xsl:value-of select="count(//Record[Description/text()=current()/Description/text()])"/></td>
</tr>
</xsl:if>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
关于xml - XSLT 忽略重复元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18897691/