如何在XSLT中引用值来应用模板?附示例XML代码
如何在XSLT中通过引用值应用模板
嘿,针对你这个需求,我来给你拆解一下怎么实现——核心就是通过ref属性的值找到对应department节点,然后给它应用模板。先把你提供的XML补全成完整可测试的版本(方便后续示例):
<?xml version="1.0" encoding="UTF-8"?> <company id="c123" name="comp 1"> <buildings> <building id="b1" name="bld1"> <department ref="d1"/> <department ref="d3"/> </building> </buildings> <departments> <department id="d1" name="IT"> <desc>Lorem ipsum</desc> <cto>Mr. X</cto> </department> <department id="d2" name="HR"> <desc>Human Resources</desc> <head>Ms. Y</head> </department> <department id="d3" name="Finance"> <desc>Money matters</desc> <head>Mr. Z</head> </department> </departments> </company>
下面给你两种常用的实现方法:
方法1:使用<xsl:key>建立索引(推荐,高效)
当你的XML数据量较大时,用key来索引节点会比直接遍历快很多。步骤如下:
- 首先在XSLT的顶层定义一个key,把
departments下的department节点用id属性作为索引键:
<xsl:key name="dept-by-id" match="departments/department" use="@id"/>
- 然后在处理
building里的department节点时,用key()函数通过ref的值找到对应的部门节点,再应用模板:
完整XSLT示例:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:key name="dept-by-id" match="departments/department" use="@id"/> <!-- 匹配根节点,开始处理 --> <xsl:template match="/"> <html> <body> <h2>Building <xsl:value-of select="company/buildings/building/@name"/> 的部门信息</h2> <xsl:apply-templates select="company/buildings/building/department"/> </body> </html> </xsl:template> <!-- 处理building下的department节点 --> <xsl:template match="building/department"> <!-- 通过ref值找到对应的部门节点 --> <xsl:variable name="target-dept" select="key('dept-by-id', @ref)"/> <div> <h3>部门:<xsl:value-of select="$target-dept/@name"/></h3> <p>描述:<xsl:value-of select="$target-dept/desc"/></p> <p>负责人:<xsl:value-of select="$target-dept/cto | $target-dept/head"/></p> </div> </xsl:template> </xsl:stylesheet>
方法2:直接通过select定位节点(适合小数据量)
如果你的XML数据量不大,也可以直接用XPath表达式在xsl:apply-templates里定位目标节点:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <body> <h2>Building <xsl:value-of select="company/buildings/building/@name"/> 的部门信息</h2> <!-- 直接定位到对应的department节点并应用模板 --> <xsl:apply-templates select="/company/departments/department[@id = /company/buildings/building/department/@ref]"/> </body> </html> </xsl:template> <!-- 匹配departments下的department节点,输出信息 --> <xsl:template match="departments/department"> <div> <h3>部门:<xsl:value-of select="@name"/></h3> <p>描述:<xsl:value-of select="desc"/></p> <p>负责人:<xsl:value-of select="cto | head"/></p> </div> </xsl:template> </xsl:stylesheet>
两种方法最终都会输出类似这样的结果:
<html> <body> <h2>Building bld1 的部门信息</h2> <div> <h3>部门:IT</h3> <p>描述:Lorem ipsum</p> <p>负责人:Mr. X</p> </div> <div> <h3>部门:Finance</h3> <p>描述:Money matters</p> <p>负责人:Mr. Z</p> </div> </body> </html>
简单总结一下:核心就是通过XPath或者key函数,把ref属性的值和目标节点的id属性关联起来,找到节点后就能正常应用模板啦~
内容的提问来源于stack exchange,提问作者4kshay
相关产品推荐
相关产品推荐

