如何在属性值匹配时基于两个XML文件编写XSL提取对应数据
XSL跨XML关联匹配修复方案
原有代码错误点
- 节点路径写错:
id属性是cc的子节点dd的属性,原有代码写为/cc[@id = ...],把属性挂在了根节点cc上,永远匹配不到目标节点 - 上下文引用错误:遍历
bb节点时current()指向当前bb元素,bb下没有dd子节点,原有判断条件current()/dd/@id取值为空 - 匹配逻辑缺失:没有实现第二层
class属性的匹配规则,也没有正确指向ee、gg节点的取值路径,导致后两列内容为空
可直接运行的正确XSL代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="aa"> <html> <body> <table> <xsl:for-each select="bb"> <!-- 提前存储当前bb节点的匹配标识,避免上下文切换导致取值错误 --> <xsl:variable name="curDate" select="@date"/> <xsl:variable name="matchId" select="@num"/> <xsl:variable name="matchClass" select="@class"/> <!-- 第一层匹配:找到2.xml中id与当前bb的num属性一致的dd节点 --> <xsl:variable name="targetDd" select="document('2.xml')/cc/dd[@id = $matchId]"/> <tr> <td><xsl:value-of select="$curDate"/></td> <!-- 取匹配dd节点下的ee值 --> <td><xsl:value-of select="$targetDd/ee"/></td> <!-- 第二层匹配:在当前dd节点下,找到class与bb的class属性一致的gg节点取值 --> <td><xsl:value-of select="$targetDd/ff/gg[@class = $matchClass]"/></td> </tr> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet>
关键逻辑说明
- 跨文件加载使用
document('2.xml')函数,加载后严格按照XML实际层级写XPath:dd是cc的直接子节点,所以路径写为/cc/dd - 双层匹配做了作用域限制:匹配gg节点时,只在已经匹配到的目标dd节点范围内查找,不会出现跨dd节点匹配class导致的取值混乱
- 提前将当前遍历节点的属性存为变量,避免在跨文件节点的XPath中出现上下文指向错误,兼容所有XSLT 1.0处理器
内容的提问来源于stack exchange,提问作者Mats Køber
相关产品推荐
相关产品推荐

