javascript XSLT节点,选择组中的第一个(类似于合并) [英] javascript XSLT nodes, selecting the first of a group (merge-like)

查看:223
本文介绍了javascript XSLT节点,选择组中的第一个(类似于合并)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在阅读了一些此处的合并帖子后,我的问题似乎更简单了,我无法找到答案.所以我发布了一个新问题.

after reading some of the merge posts out here, my question appears to be simpler and I am not capable to find out the answer. So I post a new question.

原始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页面

the xslt, used as an .xsl page to be interpreted by a browser

<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>

我得到的输出(从概念上讲,因为这是对较大代码的简化)

the output that I got (conceptually, since this is a simplification of a larger code)

<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>

以及我想要的输出,即每个序列只有一个条目,以避免产生冗余

and the output that I would like to have, i.e. to have only one entry for each sequence, so to avoid having redudancy

<peptide>
<accession>111</accession>
<sequence>AAA</sequence>
</peptide>
<peptide>
<accession>111</accession>
<sequence>BBB</sequence>
</peptide>

我很高兴只有第一个共享相同序列的节点(因此不合并它们). 任何帮助都非常受欢迎:)

I would be happy to have just the first of the nodes that share the same sequence (so not merging them). Any help is highly welcomed :)

谢谢!

推荐答案

样式表所缺少的是一种用于标识一组相同项目中的第一个的方法.以下样式表使用xsl:key通过accessionsequence值的组合将peptide元素分组:

What your stylesheet is missing is a way to identify the first in a group of identical items. The following stylesheet uses an xsl:key to group peptide elements by a combination of their accession and sequence values:

<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, sequence)的键将peptide元素分组.以后可以通过复制某些peptide元素的密钥来检索元素:

...groups peptide elements using keys whose values are equal to concat(., accession, sequence). Elements can be later retrieved by reproducing the key for some peptide element:

key('byAccSeq', concat(/path/to/peptide, accession, sequence))

要匹配为某个键返回的节点列表中的第一个元素,我们使用以下模板/模式:

To match the first element in the list of nodes returned for some key, we use the following template/pattern:

<xsl:template match="peptide[generate-id()=
               generate-id(key('byAccSeq', concat(., accession, sequence))[1])]">

generate-id函数为文档中的每个节点返回唯一的标识符.我们要求的任何peptide元素的唯一ID等于某个键列表中第一个节点的唯一ID.

The generate-id function returns a unique identifier for every node in the document. We're asking for any peptide element whose unique ID is equal to the unique ID of a node that's first in the list for some key.

然后,我们使用以下模板忽略所有其他peptide元素-不是某些键首先出现的元素:

We then ignore all other peptide elements -- the ones that aren't first for some key -- with the following template:

<xsl:template match="peptide"/>

这种分组技术称为Muenchian方法.进一步阅读:

This grouping technique is called the Muenchian Method. Further reading:

这篇关于javascript XSLT节点,选择组中的第一个(类似于合并)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆