我认为这是一个初学者问题,它涉及跨不同XSLT模板的变量引用。结构是这样的:
我首先有一个XSLT文件,在其中,我已经声明了一个模板A,在其中,我基本上遍历XML文件的每个记录(行),比如xml_A,我已经声明了变量,用于引用xml_A中当前记录的名为“id”的特定字段。然后,在这个for-each循环中,我需要调用另一个模板B.
<xsl:template name="A">
<LoopA>
<xsl:for-each select="$xml_A//xml_A_row">
<xsl:variable name="id_A" select="id"/>
....
</LoopA>
<xsl:call-template name="B"/>
</xsl:template>
对于模板B,我实际上在同一目录下创建了另一个XSLT文件。 B包含来自xml文件“xml_B”的数百万条记录,但我只想将具有SAME id字段的记录作为模板A的当前记录。以下是我的方法:
<xsl:template name="B">
<LoopB>
<xsl:variable name="id_A" select="id"/>
...
</loopB>
</xsl:template>
这是我的问题。我使用上面的<xsl:variable name="id_A" select="id"/>
来引用上层循环所在的当前记录的id字段。但是,我不确定这是否正确,我已经做了一些测试,因为数据文件非常庞大,因此在视觉上测试这是不是很容易。
所以我想知道是否有人可以建议上面对外环变量的引用是否正确,因为如果我删除它,XML编辑器会抱怨。
提前致谢。
从评论中更新
我想我没说清楚。 实际上,
xml_A
或xml_B
都不是 将成为XSLTed的xml文件。 它们只是我想要的数据文件 用来从中提取数据,并且有 另一个用于的XML文件C. 应用样式表,它是 空。所以在我的样式表中,使用 提供答案,我必须有办法 使它指的是这个数据存储 file xml_A。
答案 0 :(得分:4)
典型的XSLT样式是:
<xsl:variable name="xml_B" select="document('xml_B.xml')">
<xsl:template match="xml_A_row">
<xsl:apply-templates select="$xml_B/path/to/xml_B_row[id = current()/id]"/>
</xsl:template>
注意:模式匹配而不是xsl:for-each
和命名模板xsl:apply-templates
而不是xsl:call-template
,current()
函数来引用上下文节点。< / p>
编辑:为了看起来更像是不完整的样式表片段......
<xsl:key name="kBRowById" match="xml_B_row" use="id"/>
<xsl:variable name="xml_A" select="document('xml_A.xml')"/>
<xsl:variable name="xml_B" select="document('xml_B.xml')"/>
<xsl:template name="A">
<LoopA>
<xsl:for-each select="$xml_B">
<xsl:apply-templates select="key('kBRowById',$xml_A//xml_A_row/id)"
mode="just-in-case"/>
</xsl:for-each>
</LoopA>
</xsl:template>
<xsl:template match="xml_B_row" mode="just-in-case">
<LoopB/>
</xsl:template>
注意:使用xsl:key
,因为您编写了“毫秒记录”,xsl:for-each
具有单例根节点,以便更改fn:key()
函数的上下文节点,使用最外部范围变量$xml_A
作为交叉引用键值。 mode
就是为了防止你没有提供的样式表的其他规则发生冲突。