变量函数中的xslt动态/条件应用模板?
我想根据用户的需要显示两种不同的XSLT转换。除了一行之外,整个XSL文件都是相同的 这条线应该是这样的变量函数中的xslt动态/条件应用模板?,xslt,dynamic,conditional,apply-templates,Xslt,Dynamic,Conditional,Apply Templates,我想根据用户的需要显示两种不同的XSLT转换。除了一行之外,整个XSL文件都是相同的 这条线应该是这样的 <xsl:template match="/data/peptides/peptide[generate-id()=generate-id(key('byAccSeq', concat(protein_accessions/accession, '|', sequence))[1])]"> 然而,这只是一行,我只想维护一个文件。我想做这样的事情 <xsl:param na
<xsl:template match="/data/peptides/peptide[generate-id()=generate-id(key('byAccSeq', concat(protein_accessions/accession, '|', sequence))[1])]">
然而,这只是一行,我只想维护一个文件。我想做这样的事情
<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模板中的特性“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>
->
- 此代码不正确,因为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>
改进:最终代码更易于阅读,重复代码更少
我保留apply模板调用是因为我需要它,但是没有它们(如原始代码中所示,请参阅注释)就更简单了
再次感谢您的回答,也感谢您教授XSLT:)
及
它们是等价的generate-id()
始终返回已传递给它的节点集中第一个节点的id
因此,无论您使用生成id(某些节点集)
还是生成id(某些节点集[1])
,都没有任何区别。您可以使用任意一个XSLT文件。从
更改为
在这之后,为两个或其中一个写
以较短的方式修改您的解决方案:
我已经根据您的输入XML和输出测试了我的代码。现在我可以复制相同的
在我的代码中,我仍然可以减少更多的代码行
将
替换为以下行:-
<xsl:copy-of select="peptide[generate-id()=generate-id(key('byAccSeq', concat(accession, '|', sequence)))]"/>
检查一下..你是对的,但是在过去我能够得到的不是第一个而是所有的节点,因此我得到了一个差异(),然后现在我需要恢复它expression@Gerard例如我不知道你在那里干什么。您的“模式1”和“模式2”模板正在做完全相同的事情(即
)。有两个相等的模板有什么意义?而且,
不能是
的子脚本,因此在我看来,这段代码在语法上甚至不正确。显然,这是对更大脚本的简化。你是对的,代码在语法上是不正确的,我希望能有其他选择。虽然在语法上不正确,但我相信我想做的事情可以通过我提供的代码来理解。@Gerard提供甚至不起作用的代码一点帮助都没有。如果你的样本连编译都没有,我该怎么帮你?在我发现一个可能是你所说的问题之前,我是否应该一直猜测你的代码?认真地提供工作代码,暴露您有疑问的确切问题。我免费帮助你,这是你能做的最起码的事。我理解挫折感,但我有两个选择a)只考虑概念问题,即我想做什么,但不知道如何做,b)相同,但提供一些无用的代码,只是为了更容易理解我想做什么。我试过b),也认为代码是正确的(就是你告诉我代码没有错的那个人)。但实际上,多亏了你和西瓦·查兰,我知道我有了我想要的代码,所以问题就解决了。我已经发布了问题中的最终代码。我也知道帮助是免费的,对此我真的很感激:)我正按照你的建议努力,但没有成功。@Gerard:我已经用正确的XSLT代码(基于您的代码)更新了我的答案。现在,我可以根据您的输入XML复制相同的输出。检查一下,让我知道。非常感谢。因为我需要保留apply模板调用,所以我认为for each解决方案不起作用。相反,使用两组带有“Key”的节点并使用它们调用模板是我能想到的最简单的方法。我建议测试XSLT代码,最好使用XMLSpy。Tomalak解决方案也是一个很好的解决方案。@Gerard:您仍然在代码上使用重复的xpath和
来进行匹配和打印。请查看您的解决方案的改进版本:
<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>
/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))
)
]
<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: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>
<xsl:copy-of select="peptide[generate-id()=generate-id(key('byAccSeq', concat(accession, '|', sequence)))]"/>