首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >XSLT-1.0如何消除冗余,但选择一个特定节点而不是第一个节点

XSLT-1.0如何消除冗余,但选择一个特定节点而不是第一个节点
EN

Stack Overflow用户
提问于 2011-12-19 20:27:27
回答 1查看 197关注 0票数 2

我有一个XML

代码语言:javascript
复制
<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>

使用下面的XSLT,我可以获得带有“accession”"111“的肽,消除了序列的冗余。这样我就得到了这个XML

代码语言:javascript
复制
<root>
    <peptide>
        <accession>111</accession>
        <sequence>AAA</sequence>
        <score>4000</score>
    </peptide>
    <peptide>
        <accession>111</accession>
        <sequence>BBB</sequence>
        <score>5000</score>
    </peptide>
</root>

这就是XSLT

代码语言:javascript
复制
<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="key('byAcc','111')
            [
            generate-id()
            =
            generate-id(key('byAccSeq', concat(accession, '|', sequence))[1])
            ]">
            <xsl:sort select="sequence" data-type="text"/>
            <xsl:sort select="score" data-type="number"/>
        </xsl:apply-templates>
    </root>
</xsl:template>
<xsl:template match="/data/peptides/peptide">
    <xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>

和活动的示例here

然后,问题是,从所有冗余中,“选定”节点只是原始XML中出现的第一个节点。

我需要在所有多余的肽(即那些具有相同登录号和序列的肽)中选择得分最高的肽。

那么所希望的XML就是下面这个

代码语言:javascript
复制
<root>
    <peptide>
        <accession>111</accession>
        <sequence>AAA</sequence>
        <score>6000</score>
    </peptide>
    <peptide>
        <accession>111</accession>
        <sequence>BBB</sequence>
        <score>8000</score>
    </peptide>
</root>

如果不清楚,请让我知道,我会重新编辑问题。非常感谢。

杰拉德

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-12-19 21:20:50

此转换

代码语言:javascript
复制
<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:strip-space elements="*"/>

 <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=
    "key('byAcc','111')
            [
            generate-id()
            =
            generate-id(key('byAccSeq', concat(accession, '|', sequence))[1])
            ]">
    <xsl:sort select="sequence" data-type="text"/>
    <xsl:sort select="score" data-type="number"/>
   </xsl:apply-templates>
  </root>
 </xsl:template>

 <xsl:template match="/data/peptides/peptide">
    <xsl:for-each select=
    "key('byAccSeq', concat(accession, '|', sequence))">
      <xsl:sort select="score" data-type="number" order="descending"/>

      <xsl:if test="position() = 1">
        <xsl:copy-of select="."/>
      </xsl:if>
    </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

在所提供的XML文档上应用时的

代码语言:javascript
复制
<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>

生成所需的、正确的结果

代码语言:javascript
复制
<root>
   <peptide>
      <accession>111</accession>
      <sequence>AAA</sequence>
      <score>6000</score>
   </peptide>
   <peptide>
      <accession>111</accession>
      <sequence>BBB</sequence>
      <score>8000</score>
   </peptide>
</root>

说明

  1. 处理组中第一个元素的模板,获取当前组中的所有元素(使用key() key(),它使用代码片段来查找所有这些元素中具有最大score的元素。只输出第一个这样的元素。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8561370

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档