如何调用XSLT模板并传递父上下文,处理多Location/SubLocation场景?
实现XSLT模板调用并传递父Job节点的方案
当然可以搞定这个需求!核心思路就是精准定位每个Location/SubLocation所属的父Job节点,然后把Job节点作为参数传给你的JobRecord模板,这样不管是处理Location还是SubLocation,都能拿到Job层级的所有数据来生成记录。
我给你拆解具体实现步骤,结合示例来说明:
1. 先明确你的XML结构(假设是这样)
先模拟一个符合你描述的XML示例,方便对应XSLT逻辑:
<Jobs> <Job jobId="J001"> <JobName>前端开发工程师</JobName> <Department>技术部</Department> <Location locId="L001"> <City>北京</City> <SubLocation subLocId="SL001"> <Office>中关村大厦</Office> </SubLocation> <SubLocation subLocId="SL002"> <Office>望京科技园</Office> </SubLocation> </Location> <Location locId="L002"> <City>上海</City> </Location> </Job> </Jobs>
2. XSLT核心实现逻辑
思路关键点:
- 遍历所有需要生成记录的节点:
Job/Location(没有子节点的Location)和Job/Location/SubLocation(有子节点的子位置) - 对每个遍历到的节点,调用
JobRecord模板时,把它所属的父Job节点作为参数传递进去 - 在
JobRecord模板里,根据传入的位置节点类型(Location/SubLocation),输出对应内容
完整XSLT代码:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 主入口:匹配根节点下的Jobs,触发后续处理 --> <xsl:template match="/Jobs"> <result> <!-- 一次性选中所有需要生成记录的位置节点 --> <xsl:apply-templates select="Job/Location | Job/Location/SubLocation" /> </result> </xsl:template> <!-- 匹配Location或SubLocation节点,调用JobRecord模板并传递父Job --> <xsl:template match="Location | SubLocation"> <xsl:call-template name="JobRecord"> <!-- 用ancestor::Job[1]获取当前节点最近的父Job(避免多层嵌套的问题) --> <xsl:with-param name="currentJob" select="ancestor::Job[1]" /> <!-- 传递当前处理的位置节点 --> <xsl:with-param name="currentLocation" select="." /> </xsl:call-template> </xsl:template> <!-- 你的核心JobRecord模板,接收Job和位置节点参数 --> <xsl:template name="JobRecord"> <xsl:param name="currentJob" /> <xsl:param name="currentLocation" /> <!-- 生成一行记录 --> <record> <!-- 输出Job层级的信息 --> <JobID><xsl:value-of select="$currentJob/@jobId" /></JobID> <JobName><xsl:value-of select="$currentJob/JobName" /></JobName> <Department><xsl:value-of select="$currentJob/Department" /></Department> <!-- 根据位置节点类型输出不同内容 --> <xsl:choose> <!-- 处理没有SubLocation的Location --> <xsl:when test="$currentLocation[self::Location]"> <LocationID><xsl:value-of select="$currentLocation/@locId" /></LocationID> <City><xsl:value-of select="$currentLocation/City" /></City> <SubLocationInfo>无</SubLocationInfo> </xsl:when> <!-- 处理SubLocation --> <xsl:when test="$currentLocation[self::SubLocation]"> <LocationID><xsl:value-of select="$currentLocation/../@locId" /></LocationID> <City><xsl:value-of select="$currentLocation/../City" /></City> <SubLocationID><xsl:value-of select="$currentLocation/@subLocId" /></SubLocationID> <Office><xsl:value-of select="$currentLocation/Office" /></Office> </xsl:when> </xsl:choose> </record> </xsl:template> </xsl:stylesheet>
3. 关键细节说明
- 获取父Job节点:用
ancestor::Job[1]可以精准定位当前位置节点所属的最近的Job父节点,即使XML结构有多层嵌套也不会出错。 - 模块化拆分:把生成记录的逻辑封装在
JobRecord模板里,不管是Location还是SubLocation都复用同一个模板,逻辑更清晰,也方便后续维护。 - 兼容性:上面的代码是XSLT 1.0版本,几乎所有XSLT处理器都支持;如果你的环境支持XSLT 2.0+,还可以用更简洁的
for-each或者xsl:sequence写法,但1.0的写法兼容性最好。
这样处理后,每个Location和SubLocation都会对应生成一行包含Job信息的记录,完全符合你的需求。
内容的提问来源于stack exchange,提问作者joynoele
相关产品推荐
相关产品推荐

