【发布时间】:2011-12-19 18:39:12
【问题描述】:
我有一个包含一组 protein 节点的 XML 文件,每个节点都有一个 accession 编号。还有一组peptides,每个都带有accession、sequence、RT和score参数。
我有一个 XSLT 文件,它为每种蛋白质调用具有相同accession 蛋白质编号的所有肽节点。
然后,根据变量的值,此处为<xsl:param name="analysis" select="0"/>,XSLT 文件调用所有共享相同accession 编号的肽段,或所有共享相同accession 编号但丢弃所有这些肽段的肽段具有重合的sequence 值。
这是我所说的代码(将变量的值从0更改为1,可以看到我描述的2种情况)
我也把代码贴在文末
现在,我需要做的是排序和选择得分最高的肽节点。
因此,在 XSLT 文件调用共享相同accession 编号的所有肽段的情况下,我需要根据其分值对它们进行排序。
并且,如果代码调用所有共享相同accession 编号的肽,但只选择那些也共享相同序列的肽中的一个肽,我需要这个肽是得分最高的肽,不仅仅是 XML 文件中的第一个。
我曾尝试在此代码link 中使用“排序”功能,但如果您查看一下,您会看到 XML 输出对所有肽段进行排序,丢失了之前使用key 声明。
XML 代码
<data>
<proteins>
<protein>
<accession>111</accession>
</protein>
</proteins>
<peptides>
<peptide>
<accession>111</accession>
<sequence>AAA</sequence>
<RT>13</RT>
<score>4000</score>
</peptide>
<peptide>
<accession>111</accession>
<sequence>AAA</sequence>
<RT>14</RT>
<score>6000</score>
</peptide>
<peptide>
<accession>111</accession>
<sequence>AAA</sequence>
<RT>15</RT>
<score>5000</score>
</peptide>
<peptide>
<accession>111</accession>
<sequence>BBB</sequence>
<RT>23</RT>
<score>5000</score>
</peptide>
<peptide>
<accession>111</accession>
<sequence>BBB</sequence>
<RT>24</RT>
<score>1000</score>
</peptide>
<peptide>
<accession>111</accession>
<sequence>BBB</sequence>
<RT>25</RT>
<score>8000</score>
</peptide>
<peptide>
<accession>111</accession>
<sequence>BBB</sequence>
<RT>26</RT>
<score>5000</score>
</peptide>
</peptides>
</data>
XSLT 代码
<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:param name="analysis" select="0"/>
<xsl:key name="byAcc" match="/data/peptides/peptide" use="accession" />
<xsl:key name="byAccSeq" match="/data/peptides/peptide" use="concat(accession, '|', sequence)"/>
<xsl:template match="/">
<root>
<name>
<xsl:value-of select="$analysis"/>
</name>
<xsl:apply-templates select="/data/proteins/protein" />
</root>
</xsl:template>
<xsl:template match="/data/proteins/protein">
<xsl:choose>
<xsl:when test="$analysis=1">
<xsl:apply-templates select="key('byAcc',accession)">
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="key('byAcc',accession)[
generate-id()
=
generate-id(key('byAccSeq', concat(accession, '|', sequence)))]">
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="/data/peptides/peptide">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
以及我需要的 XML 输出,为简单起见,仅选择了一种肽 <xsl:param name="analysis" select="0"/>
<root>
<name>0</name>
<peptide>
<accession>111</accession>
<sequence>AAA</sequence>
<RT>14</RT>
<score>6000</score>
</peptide>
<peptide>
<accession>111</accession>
<sequence>BBB</sequence>
<RT>25</RT>
<score>8000</score>
</peptide>
</root>
这是来自共享 accession 和 sequence 值的 2 个肽节点,具有最大 score 值的那些
谢谢
----------------------------------------------- ----------------------------------------
编辑:试图让问题更清楚
我能想到的最简化的代码是:
我有这个 XML 代码
<data>
<peptides>
<peptide>
<accession>111</accession>
<sequence>AAA</sequence>
<score>4000</score>
</peptide>
<peptide>
<accession>111</accession>
<sequence>AAA</sequence>
<score>6000</score>
</peptide>
<peptide>
<accession>111</accession>
<sequence>AAA</sequence>
<score>5000</score>
</peptide>
<peptide>
<accession>111</accession>
<sequence>BBB</sequence>
<score>5000</score>
</peptide>
<peptide>
<accession>111</accession>
<sequence>BBB</sequence>
<score>1000</score>
</peptide>
<peptide>
<accession>111</accession>
<sequence>BBB</sequence>
<score>8000</score>
</peptide>
<peptide>
<accession>111</accession>
<sequence>BBB</sequence>
<score>5000</score>
</peptide>
<peptide>
<accession>222</accession>
<sequence>CCC</sequence>
<score>5000</score>
</peptide>
<peptide>
<accession>222</accession>
<sequence>CCC</sequence>
<score>9000</score>
</peptide>
<peptide>
<accession>222</accession>
<sequence>CCC</sequence>
<score>2000</score>
</peptide>
</peptides>
</data>
不假设它的排序方式是一致的,所以这个 XML 可以有任何位置的节点。
然后,我想要的是首先按加入对节点进行分组,然后在这些节点中按顺序对它们进行分组,然后在这些节点中按分数对它们进行排序。
所以输出的 XML 会是这样的
<data>
<peptides>
<peptide>
<accession>111</accession>
<sequence>AAA</sequence>
<score>6000</score>
</peptide>
<peptide>
<accession>111</accession>
<sequence>AAA</sequence>
<score>5000</score>
</peptide>
<peptide>
<accession>111</accession>
<sequence>AAA</sequence>
<score>4000</score>
</peptide>
<peptide>
<accession>111</accession>
<sequence>BBB</sequence>
<score>8000</score>
</peptide>
<peptide>
<accession>111</accession>
<sequence>BBB</sequence>
<score>5000</score>
</peptide>
<peptide>
<accession>111</accession>
<sequence>BBB</sequence>
<score>5000</score>
</peptide>
<peptide>
<accession>111</accession>
<sequence>BBB</sequence>
<score>1000</score>
</peptide>
<peptide>
<accession>222</accession>
<sequence>CCC</sequence>
<score>9000</score>
</peptide>
<peptide>
<accession>222</accession>
<sequence>CCC</sequence>
<score>5000</score>
</peptide>
<peptide>
<accession>222</accession>
<sequence>CCC</sequence>
<score>2000</score>
</peptide>
</peptides>
</data>
最后一个代码的解决方案,来自提供的答案:
<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="byAcc" match="/data/peptides/peptide" use="accession" />
<xsl:key name="byAccSeq" match="/data/peptides/peptide" use="concat(accession, '|', sequence)"/>
<xsl:template match="/">
<root>
<xsl:apply-templates select="/data/proteins/protein">
</xsl:apply-templates>
</root>
</xsl:template>
<xsl:template match="/data/proteins/protein">
<xsl:apply-templates select="key('byAcc',accession)">
<xsl:sort select="sequence" data-type="text"/>
<xsl:sort select="score" data-type="number"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="/data/peptides/peptide">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
查看here
【问题讨论】:
-
通过升序对 XML 文档进行初始排序然后应用转换是否可以解决问题?请您解释一下您希望转换做什么?目前的措辞相当混乱。也许,如果你能提供一个完全简化的小例子,它会更容易理解。然后,当发布此简化示例的解决方案时,您可以将其应用于您的特定问题。
-
对不起,这是试图提供一个简单的例子。我将编辑问题。
-
@_Gerard:感谢您的编辑。似乎如果您对 XML 文档进行预排序(按
score递增)——我的回答中的两个解决方案中的第一个。