在阅读了这里的一些合并帖后,我的问题看起来更简单了,我无法找到答案。所以我发布了一个新问题。
原始xml
<data>
<proteins>
<protein>
<accession>111</accession>
</protein>
</proteins>
<peptides>
<peptide>
<accession>111</accession>
<sequence>AAA</sequence>
</peptide>
<peptide>
<accession>111</accession>
<sequence>AAA</sequence>
</peptide>
<peptide>
<accession>111</accession>
<sequence>AAA</sequence>
</peptide>
<peptide>
<accession>111</accession>
<sequence>BBB</sequence>
</peptide>
<peptide>
<accession>111</accession>
<sequence>BBB</sequence>
</peptide>
<peptide>
<accession>111</accession>
<sequence>BBB</sequence>
</peptide>
<peptide>
<accession>111</accession>
<sequence>BBB</sequence>
</peptide>
</peptides>
</data>
xslt,用作浏览器解释的.xsl页面
<xsl:template match="/">
<xsl:apply-templates select="/data/proteins/protein" />
</xsl:template>
<xsl:template match="/data/proteins/protein">
<xsl:apply-templates select="/data/peptides/peptide[accession = current()/accession]" >
</xsl:template>
<xsl:template match="/data/peptides/peptide">
...
</xsl:template>
我得到的输出(概念上,因为这是对更大代码的简化)
<peptide>
<accession>111</accession>
<sequence>AAA</sequence>
</peptide>
<peptide>
<accession>111</accession>
<sequence>AAA</sequence>
</peptide>
<peptide>
<accession>111</accession>
<sequence>AAA</sequence>
</peptide>
<peptide>
<accession>111</accession>
<sequence>BBB</sequence>
</peptide>
<peptide>
<accession>111</accession>
<sequence>BBB</sequence>
</peptide>
<peptide>
<accession>111</accession>
<sequence>BBB</sequence>
</peptide>
<peptide>
<accession>111</accession>
<sequence>BBB</sequence>
</peptide>
和我想要的输出,即每个序列只有一个条目,以避免减少
<peptide>
<accession>111</accession>
<sequence>AAA</sequence>
</peptide>
<peptide>
<accession>111</accession>
<sequence>BBB</sequence>
</peptide>
我很高兴只拥有共享相同序列的第一个节点(因此不合并它们)。 任何帮助都非常欢迎:)
谢谢!
答案 0 :(得分:2)
缺少样式表的方法是识别一组相同项目中的第一个。以下样式表使用xsl:key
通过peptide
和accession
值的组合对sequence
元素进行分组:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:key name="byAccSeq" match="peptide"
use="concat(accession, '|', sequence)"/>
<xsl:template match="/">
<root><xsl:apply-templates select="/*/proteins/protein"/></root>
</xsl:template>
<xsl:template match="protein">
<xsl:apply-templates
select="../../peptides/peptide[accession=current()/accession]"/>
</xsl:template>
<xsl:template match="peptide[generate-id()=
generate-id(key('byAccSeq', concat(accession, '|', sequence))[1])]">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="peptide"/>
</xsl:stylesheet>
输出:
<root>
<peptide>
<accession>111</accession>
<sequence>AAA</sequence>
</peptide>
<peptide>
<accession>111</accession>
<sequence>BBB</sequence>
</peptide>
</root>
说明:以下一行:
<xsl:key name="byAccSeq" match="peptide"
use="concat(., accession, sequence)"/>
...使用值等于peptide
的键对concat(., accession, sequence)
个元素进行分组。稍后可以通过复制某些peptide
元素的键来检索元素:
key('byAccSeq', concat(/path/to/peptide, accession, sequence))
要匹配为某个键返回的节点列表中的第一个元素,我们使用以下模板/模式:
<xsl:template match="peptide[generate-id()=
generate-id(key('byAccSeq', concat(., accession, sequence))[1])]">
generate-id
函数为文档中的每个节点返回唯一标识符。我们要求任何peptide
元素,其唯一ID等于某个键列表中第一个节点的唯一ID。
然后我们忽略所有其他peptide
元素 - 那些不是某些键的第一个元素 - 使用以下模板:
<xsl:template match="peptide"/>
这种分组技术称为Muenchian方法。进一步阅读:
答案 1 :(得分:1)
备用Muenchian grouping (只有一个模板和一条指令):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kPepByAccAndSeq" match="peptide"
use="concat(accession, '+', sequence)"/>
<xsl:template match="/">
<xsl:copy-of select=
"/*/peptides
/peptide
[generate-id()
=
generate-id(key('kPepByAccAndSeq',
concat(accession, '+', sequence)
)[1]
)
]
"/>
</xsl:template>
</xsl:stylesheet>
将此转换应用于提供的XML文档:
<data>
<proteins>
<protein>
<accession>111</accession>
</protein>
</proteins>
<peptides>
<peptide>
<accession>111</accession>
<sequence>AAA</sequence>
</peptide>
<peptide>
<accession>111</accession>
<sequence>AAA</sequence>
</peptide>
<peptide>
<accession>111</accession>
<sequence>AAA</sequence>
</peptide>
<peptide>
<accession>111</accession>
<sequence>BBB</sequence>
</peptide>
<peptide>
<accession>111</accession>
<sequence>BBB</sequence>
</peptide>
<peptide>
<accession>111</accession>
<sequence>BBB</sequence>
</peptide>
<peptide>
<accession>111</accession>
<sequence>BBB</sequence>
</peptide>
</peptides>
</data>
产生了想要的正确结果:
<peptide>
<accession>111</accession>
<sequence>AAA</sequence>
</peptide>
<peptide>
<accession>111</accession>
<sequence>BBB</sequence>
</peptide>
解释:Muenchian分组,其中键值是两个元素值的组合。