XSL:根据变量的值从节点中选择数据

时间:2011-06-09 16:17:38

标签: xml xslt

我正在研究一个学习XSL的小项目,我遇到了一个问题......

我有一个Docbook文件,其中包含一系列由Department分类的人员。然而,偶尔我会有一个人在一个小组和他自己的小组中工作。为避免重复数据,我指定人员节点或者包含节点中的数据,或者包含链接到其主节点的外部参照节点。当我遍历组中的所有人时,我需要检查节点是链接节点还是数据节点,并相应地调整我的变量。

这是选择代码

<xsl:choose>
    <xsl:when test="xref">
        <xsl:variable name="TAG_ID" select="xref/@linkend" />
        <xsl:variable name="NAME" select="//*[@id='$TAG_ID']/para[@id='who']" />
        <xsl:variable name="EMAIL" select="//*[@id='$TAG_ID']/para[@id='who']/ulink/@url" />
        <xsl:variable name="IMAGE" select="//*[@id='$TAG_ID']/para[@id='image']" />
        <xsl:variable name="MEET" select="//*[@id='$TAG_ID']/para[@id='meet']" />
        <xsl:call-template name="output_person" />
    </xsl:when>
    <xsl:otherwise>
        <xsl:variable name="NAME" select="para[@id ='who']" />
        <xsl:variable name="EMAIL" select="para[@id='who']/ulink/@url" />
        <xsl:variable name="IMAGE" select="para [@id='image']" />
        <xsl:variable name="MEET" select="para [@id='meet']" />
        <xsl:call-template name="output_person" />
    </xsl:otherwise>
</xsl:choose>

然而,当我尝试运行此操作时,我收到以下错误...

runtime error: file team.xsl line 92 element img
Variable 'IMAGE' has not been declared.
xmlXPathCompiledEval: evaluation failed

在看了一些互联网之后,我同时看到了完成这个的代码,人们说它不可能。

所以我的问题是双重的......

我可以根据变量选择特定节点吗?

如果没有,甚至可以这样做吗?

1 个答案:

答案 0 :(得分:1)

您声明的变量不在output_person模板的范围内。为了使其工作,您需要让output_person模板接受params,然后将这些params作为call-template的一部分传递。

另请注意,对变量的引用不应用引号括起来。

例如:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- other templates -->
<xsl:template match="your-element">
    <xsl:choose>
        <xsl:when test="xref">
            <xsl:variable name="TAG_ID" select="xref/@linkend" />
            <xsl:variable name="NAME" select="//*[@id=$TAG_ID]/para[@id='who']" />
            <xsl:variable name="EMAIL" select="//*[@id=$TAG_ID]/para[@id='who']/ulink/@url" />
            <xsl:variable name="IMAGE" select="//*[@id=$TAG_ID]/para[@id='image']" />
            <xsl:variable name="MEET" select="//*[@id=$TAG_ID]/para[@id='meet']" />
            <xsl:call-template name="output_person">
               <xsl:with-param name="NAME" select="$NAME"/> 
                <xsl:with-param name="EMAIL" select="$EMAIL"/> 
                <xsl:with-param name="IMAGE" select="$IMAGE"/> 
                <xsl:with-param name="MEET" select="$MEET"/> 
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:variable name="NAME" select="para[@id ='who']" />
            <xsl:variable name="EMAIL" select="para[@id='who']/ulink/@url" />
            <xsl:variable name="IMAGE" select="para [@id='image']" />
            <xsl:variable name="MEET" select="para [@id='meet']" />
            <xsl:call-template name="output_person">
                <xsl:with-param name="NAME" select="$NAME"/> 
                <xsl:with-param name="EMAIL" select="$EMAIL"/> 
                <xsl:with-param name="IMAGE" select="$IMAGE"/> 
                <xsl:with-param name="MEET" select="$MEET"/> 
            </xsl:call-template>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>
<xsl:template name="output_person">
    <xsl:param name="NAME"/>
    <xsl:param name="EMAIL"/>
    <xsl:param name="IMAGE"/>
    <xsl:param name="MEET"/>
    <!-- your logic here -->
</xsl:template>