Я хочу показать два разных преобразования XSLT в зависимости от того, чего хочет пользователь. Весь XSL-файл является одним и тем же, за исключением одной строки.xslt динамический/условный шаблон apply в функции переменной?
Эта линия должна быть как
<xsl:template match="/data/peptides/peptide[generate-id()=generate-id(key('byAccSeq', concat(protein_accessions/accession, '|', sequence))[1])]">
или как его
<xsl:template match="/data/peptides/peptide">
Моя первая мысль была создать два различных файла .xsl, и применять их (JavaScript) в зависимости от а значение переменной.
var xsltProcessor = new XSLTProcessor();
xsltProcessor.importStylesheet(xslDoc);
xhtml = xsltProcessor.transformToFragment(xmlDoc,document);
Однако, это всего лишь строка, и я хотел бы сохранить только один файл. Я хотел бы сделать что-то вроде этого
<xsl:param name="variable"/>
<xsl:choose>
<xsl:when test="$variable = 0">
<xsl:template match="/data/peptides/peptide[generate-id()=generate-id(key('byAccSeq', concat(protein_accessions/accession, '|', sequence))[1])]">
...
</xsl:template>
</xsl:when>
<xsl:otherwise>
<xsl:template match="/data/peptides/peptide">
...
</xsl:template>
</xsl:otherwise>
</xsl:choose>
Но это не работает.
пытается с "режимом" особенность в XSL: не применять-шаблоны, этот код ни работает
<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="/data/peptides/peptide" use="concat(accession, '|', sequence)"/>
<xsl:param name="analysis" select="1"/>
<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:apply-templates select="/data/peptides/peptide[accession=current()/accession]"/>
</xsl:template>
<xsl:choose>
<xsl:when test="$analysis=1">
<xsl:apply-templates select="/data/peptides/peptide" mode="one"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="/data/peptides/peptide[accession=current()/accession]" mode="two"/>
</xsl:otherwise>
</xsl:choose>
<xsl:template match="/data/peptides/peptide" mode="one">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="/data/peptides/peptide[generate-id()=
generate-id(key('byAccSeq', concat(accession, '|', sequence))[1])]" mode="two">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
->http://www.xsltcake.com/slices/sgWUFu/2
- этот код не является правильным, так как XSL: выбор не может быть ребенок XSL: таблица стилей
РЕШИТЬ (улучшенный ниже), это код, который делает то, что я хотел
<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="/data/peptides/peptide" use="concat(accession, '|', sequence)"/>
<xsl:param name="analysis" select="1"/>
<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="/data/peptides/peptide[accession=current()/accession]" mode="one"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="/data/peptides/peptide[accession=current()/accession]" mode="two"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="/data/peptides/peptide" mode="one">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="/data/peptides/peptide" mode="two"/>
<xsl:template match="/data/peptides/peptide[generate-id()=
generate-id(key('byAccSeq', concat(accession, '|', sequence)))]" mode="two">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
ПОВЫШЕНИЕ: окончательный код намного легче читать с гораздо менее дублированным кодом here
<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:when>
<xsl:otherwise>
<xsl:apply-templates select="key('byAcc',accession)[
generate-id()
=
generate-id(key('byAccSeq', concat(accession, '|', sequence)))]" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="/data/peptides/peptide">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
я держу применить-шаблон вызовы, потому что мне это нужно, но без них (как и в оригинале код, см. комментарии) еще проще.
Еще раз спасибо, не только для ответа, но для обучения XSLT :)
Посмотрите на улучшенной версии вашего решения: http://www.xsltcake.com/slices/sgWUFu/5 – Tomalak