阅读了这里的一些合并帖子后,我的问题似乎更简单,我无法找到答案。所以我提出了一个新问题。
原始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>
我很高兴只拥有共享相同序列的第一个节点(因此不合并它们)。 非常欢迎任何帮助:)
谢谢!
最佳答案
您的样式表缺少的是一种识别一组相同项目中第一个项目的方法。以下样式表使用 xsl:key
通过 accession
和 sequence
值的组合对 peptide
元素进行分组:
<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)"/>
...使用值等于 concat(., accession,equence)
的键对 peptide
元素进行分组。稍后可以通过复制某些肽
元素的 key 来检索元素:
key('byAccSeq', concat(/path/to/peptide, accession, sequence))
为了匹配某个键返回的节点列表中的第一个元素,我们使用以下模板/模式:
<xsl:template match="peptide[generate-id()=
generate-id(key('byAccSeq', concat(., accession, sequence))[1])]">
generate-id
函数返回文档中每个节点的唯一标识符。我们要求提供唯一 ID 等于某个键列表中第一个节点的唯一 ID 的任何peptide
元素。
然后,我们使用以下模板忽略所有其他 peptide
元素(那些不是某些键的第一个元素):
<xsl:template match="peptide"/>
这种分组技术称为 Muenchian 方法。进一步阅读:
关于xslt - javascript XSLT 节点,选择组中的第一个(类似合并),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8466734/