Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
变量函数中的xslt动态/条件应用模板?_Xslt_Dynamic_Conditional_Apply Templates - Fatal编程技术网

变量函数中的xslt动态/条件应用模板?

变量函数中的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

我想根据用户的需要显示两种不同的XSLT转换。除了一行之外,整个XSL文件都是相同的

这条线应该是这样的

<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)))]"/>