如何在XSLT的for-each循环中比较不同节点的属性
优化XSLT匹配bike与car节点的逻辑(XSLT 2.0版本)
嘿,很高兴你已经定位到问题根源是命名空间使用错误,而且现有代码已经能正常运行啦!不过确实,借助XSLT 2.0的特性,我们可以把这段代码的逻辑简化得更清晰、更易维护,同时精准达成你想要的输出结果「TEST - 4 2」。
先明确下核心需求:匹配bike和car节点的id属性,当二者id相等且car的color为blue时,输出该car的misc属性。
原始XML结构
<?xml version="1.0" encoding="UTF-8"?> <test> <cars> <car id="1" color="blue" misc="4"/> <car id="2" color="red" misc="3"/> <car id="3" color="blue" misc="2"/> <car id="n" color="black" misc="1"/> </cars> <bikes> <bike id="1"/> <bike id="2"/> <bike id="3"/> <bike id="n"/> </bikes> </test>
你当前的XSLT 1.0代码
<?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>TEST - </h2> <xsl:variable name="bikes" select="test/bikes/bike"/> <xsl:variable name="cars" select="test/cars/car"/> <xsl:for-each select="$bikes"> <xsl:variable name="bikesID" select="./@id"/> <xsl:for-each select="$cars"> <xsl:if test="$bikesID = ./@id"> <xsl:if test="./@color = 'blue'"> <xsl:value-of select="./@misc"/> </xsl:if> </xsl:if> </xsl:for-each> </xsl:for-each> </body> </html> </xsl:template> </xsl:stylesheet>
优化后的XSLT 2.0代码
这里提供两种优化方案,都能达到目标且逻辑更简洁:
方案1:使用xsl:key快速匹配(推荐,大数据量场景性能更优)
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 预先索引所有color为blue的car,用id作为匹配键 --> <xsl:key name="blue-cars-by-id" match="car[@color='blue']" use="@id"/> <xsl:template match="/"> <html> <body> <h2>TEST - <!-- 直接遍历bike,通过key找到对应id的blue car,输出misc值,用空格分隔 --> <xsl:value-of select="test/bikes/bike/key('blue-cars-by-id', @id)/@misc" separator=" "/> </h2> </body> </html> </xsl:template> </xsl:stylesheet>
方案2:用XPath谓词直接过滤(简洁直观,小数据量友好)
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <body> <h2>TEST - <!-- 直接筛选出符合条件的car:color为blue且id存在于bike的id列表中,输出misc值 --> <xsl:value-of select="test/cars/car[@color='blue' and @id = /test/bikes/bike/@id]/@misc" separator=" "/> </h2> </body> </html> </xsl:template> </xsl:stylesheet>
优化亮点
- 砍掉了嵌套
for-each和多层if判断,逻辑一眼就能看懂,代码量大幅减少 xsl:key方案通过预先索引,避免了重复遍历节点,数据量大时性能提升明显- 利用XSLT 2.0的
separator属性,自动用空格分隔输出的misc值,无需手动处理格式
内容的提问来源于stack exchange,提问作者Lucas Berbetz
相关产品推荐
相关产品推荐

