我是XSLT的新手,并且还没有使用它的语法。
我有一个变量(name =" pageName"),它包含xml源树中页面元素的xpath。例如:
/数据/全树/页[@Handle ='恩'] /页[@Handle ='学习'] /页[@Handle ='教程& #39]
在html页面中显示此页面的链接之前,我想确保页面元素存在,因此我编写了以下 if test:
<xsl:if test="$pageName" >
<a>
<xsl:attribute name="href" >
<xsl:value-of select='$theLink' />
</xsl:attribute>
Click here
</a>
</xsl:if>
但它没有按预期工作,因为即使xpath指向的页面元素不存在于树中,测试结果也始终为true。 另一方面,当我将变量的内容直接写入测试变量时,如下所示:
<xsl:if test="/data/full-tree/page[@handle='en']/page[@handle='learn']/page[@handle='tutorials']
<a>
<xsl:attribute name="href" >
<xsl:value-of select='$theLink' />
</xsl:attribute>
Click here
</a>
</xsl:if>
它似乎工作并在页面元素存在时显示链接,但在页面元素不存在时显示。
我的问题是如何正确使用我的变量?
修改
我会尝试让我的背景更加详细
xml源代码树(代表网站的结构就像这样
<data>
<full-tree>
<page handle="root" id="12">
<name>Root Page</name>
<types>
<type>index</type>
</types>
</page>
<page handle="en" id="1">
<name>EN Root</name>
<types>
<type>en</type>
</types>
<page handle="home" id="3">
<name>Home</name>
<types>
<type>en</type>
</types>
</page>
<page handle="about" id="7">
<name>About</name>
<types>
<type>en</type>
</types>
<page handle="about-zoraldia" id="8">
<name>About zoraldia</name>
<types>
<type>en</type>
</types>
</page>
</page>
<page handle="learn" id="21">
<name>Learn</name>
<types>
<type>en</type>
</types>
<page handle="tutorials" id="22">
<name>Tutorials</name>
<types>
<type>en</type>
</types>
<page handle="symphony" id="24">
<name>Symphony</name>
<types>
<type>en</type>
</types>
<page handle="create-site" id="23">
<name>Create a bilingual Web Site with the Symphony CMS</name>
<types>
<type>en</type>
<type>web-site</type>
</types>
</page>
<page handle="symphony-menu-page" id="48">
<name>Add level 3 and 4 Menu Pages</name>
<types>
<type>en</type>
<type>symphony</type>
</types>
</page>
</page>
</page>
</page>
<page handle="think" id="49">
<name>Think</name>
<types>
<type>en</type>
</types>
<page handle="free-software" id="50">
<name>Free Software</name>
<types>
<type>en</type>
</types>
<page handle="miscellaneous" id="51">
<name>Miscellaneous Articles</name>
<types>
<type>en</type>
</types>
<page handle="philo" id="52">
<name>Philosophy and Values of Free Software</name>
<types>
<type>en</type>
</types>
</page>
</page>
</page>
</page>
</page>
<page handle="maintenance" id="9">
<name>Maintenance notification</name>
<types>
<type>maintenance</type>
</types>
</page>
</full-tree>
<data>
这表示英文页面,但法语中也有待处理的结构。 我想要做的是当访问者在法语页面上时,仅在页面被翻译时显示EN链接。
因此我使用法语路径(例如/ fr / learn / tutorials,只需将fr与/ en / learn / tutorials交换为$ enLink变量。
我的目标是显示只有在页面存在时才能正常运行的链接。
我使用一个定义为
的变量 <xsl:variable name="pending">
<xsl:call-template name="build-xpath">
<xsl:with-param name="output-string" select="'/data/full-tree'" />
<xsl:with-param name="input-string" select="substring-after($enLink,'/')" />
</xsl:call-template>
</xsl:variable>
build-xpath算法如下:
<xsl:template name="build-xpath" >
<xsl:param name="output-string" />
<xsl:param name="input-string" />
<xsl:choose>
<xsl:when test="contains($input-string, '/')" >
<xsl:variable name="new-output">
<xsl:value-of select="$output-string" />/page[@handle='<xsl:value-of select="substring-before($input-string,'/')"/>']
</xsl:variable>
<xsl:variable name="new-input" >
<xsl:value-of select="substring-after($input-string,'/')" />
</xsl:variable >
<xsl:call-template name="build-xpath" >
<xsl:with-param name="output-string" select="$new-output" />
<xsl:with-param name="input-string" select="$new-input" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise><xsl:value-of select="$output-string"/>/page[@handle='<xsl:value-of select="$input-string"/>']
</xsl:otherwise>
</xsl:choose>
</xsl:template>
此算法返回挂起的变量(我最初称为 pageName 的变量)
以
显示<xsl:value-of select="$pending" />
我看到了字符串
/数据/全树/页[@Handle =&#39;恩&#39;] /页[@Handle =&#39;学习&#39;] /页[@Handle =&#39;教程& #39]
这是我对算法的期望。
让我遇到麻烦的是,当我将此字符串放入另一个变量时,请说 anotherVar
<xsl:value-of select="$anotherVariable"
不显示字符串,但显示节点的内容,在这种情况下:
教程en
这看起来很正常,但为什么在$ pending的情况下显示字符串本身?
答案 0 :(得分:2)
由于您的变量是字符串,因此在布尔测试中对其进行评估将始终返回true,因为只有空字符串的计算结果为false。
为了将变量评估为节点,您需要首先将字符串转换为Xpath表达式。这可以在XSLT 3.0中本机完成。在以前的版本中,您需要使用扩展功能,例如EXSLT dyn:evaluate()函数 - 如果您的处理器支持它。
可能有一种更简单的方法来处理这个问题,但我们没有看到足够的整个画面以确定(我在输入中没有看到任何法语元素)。我怀疑,例如,通过使用某个公共ID来测试是否存在相应的节点会更加直接。