我希望根据用户的需要显示两种不同的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中的“mode”功能,此代码既不起作用
<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>
- &GT; http://www.xsltcake.com/slices/sgWUFu/2
求助(下面改进),这是制作我想要的代码
<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>
我保留了apply-template调用,因为我需要它,但没有它们(如在原始代码中,请参阅注释)甚至更简单。
再次感谢,不仅是为了回答,还为了教授XSLT:)
答案 0 :(得分:1)
/data/peptides/peptide[
generate-id()
=
generate-id(
key('byAccSeq', concat(protein_accessions/accession, '|', sequence))[1]
)
]
和
/data/peptides/peptide[
generate-id()
=
generate-id(
key('byAccSeq', concat(protein_accessions/accession, '|', sequence))
)
]
是等价的。 generate-id()
始终返回已传递给它的节点集中第一个节点的ID。
因此,无论您使用generate-id(some-node-set)
还是generate-id(some-node-set[1])
,都没有任何区别。您可以使用其中一个XSLT文件。
答案 1 :(得分:1)
从<xsl:template>
更改为<xsl:apply-templates>
<xsl:apply-templates select="/data/peptides/peptide[generate-id()=generate-id(key('byAccSeq', concat(protein_accessions/accession, '|', sequence))[1])]" mode="type1" />
<xsl:apply-templates select="/data/peptides/peptide[generate-id()=generate-id(key('byAccSeq', concat(protein_accessions/accession, '|', sequence)))]" mode="type2" />
之后,相应地为这两者写一个<xsl:template>
。
<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="2"/>
<xsl:template match="/">
<root>
<name>
<xsl:value-of select="$analysis"/>
</name>
<xsl:apply-templates select="data[peptides/peptide/accession=proteins/protein/accession]/peptides" />
</root>
</xsl:template>
<xsl:template match="peptides">
<xsl:choose>
<xsl:when test="$analysis=1">
<xsl:copy-of select="peptide"/>
</xsl:when>
<xsl:otherwise>
<xsl:for-each select="peptide[generate-id()=generate-id(key('byAccSeq', concat(accession, '|', sequence)))]">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
我已根据您的输入XML&amp;测试了我的代码输出。现在我可以复制它。
在我的代码中,我仍然可以减少一些代码行
将<xsl:for-each>
替换为以下行: -
<xsl:copy-of select="peptide[generate-id()=generate-id(key('byAccSeq', concat(accession, '|', sequence)))]"/>
检查出来..