我想根据用户想要的功能显示两种不同的 XSLT 转换。整个 XSL 文件是相同的,除了一行。
这条线应该是这样
<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:apply-templates 中的功能“模式”,此代码均不起作用
<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:choose 不能是 xsl:stylesheet 的子级
已解决(在下面进行了改进),这是实现我想要的代码
<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>
改进:最终代码更容易阅读,此处重复的代码更少
<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>
我保留 apply-template 调用是因为我需要它,但没有它们(如在原始代码中,请参阅注释)甚至更简单。
再次感谢,不仅是为了回答,也是为了教授 XSLT :)