XSLT-узлы javascript, выбирающие первый из группы (подобный слиянию) - PullRequest
2 голосов
/ 11 декабря 2011

после прочтения некоторых постов слияния, мой вопрос кажется более простым, и я не могу найти ответ. Поэтому я отправляю новый вопрос.

Оригинальный 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>

Я был бы рад иметь только первый из узлов, которые имеют одинаковую последовательность (поэтому не объединять их). Любая помощь приветствуется:)

Спасибо!

Ответы [ 2 ]

2 голосов
/ 12 декабря 2011

То, что отсутствует в вашей таблице стилей, - это способ идентифицировать первое в группе идентичных элементов.Следующая таблица стилей использует 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, уникальный идентификатор которого равен уникальному идентификатору узла, который является первым в списке для некоторого ключа.

Затем мы игнорируем все остальные элементы peptide - те, чтокоторые не являются первыми для некоторого ключа - со следующим шаблоном:

<xsl:template match="peptide"/>

Этот метод группировки называется методом Мюнхена.Дополнительное чтение:

1 голос
/ 12 декабря 2011

Альтернативная мюнхенская группировка (только один шаблон и одна инструкция):

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

, когда это преобразование применяется к предоставленному XMLdocument :

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

Объяснение : мюнхенская группировка, где ключзначение является комбинацией значений двух элементов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...