XSLT技术问题:xsl:value-of无法过滤,城市关联国家显示异常
问题分析与解决方案
我看了你的XML数据和XSLT代码,发现几个关键问题导致国家显示异常、排序逻辑错误,以及纬度筛选可能不准确。下面逐一拆解并给出修正方案:
核心问题梳理
- 国家名称匹配错误:原代码中
//country[@id = @country]/name的上下文混乱,两个@country都指向当前<city>节点的属性,无法正确关联到所属国家。 - 排序逻辑失效:第一个排序规则
/mondial/country/name是从根节点取所有国家名称,而非当前城市所属国家的名称,导致排序混乱。 - 纬度比较为字符串类型:
@latitude >= '41.4'是字符串比较,会出现数值逻辑错误(比如"100"字符串会被判定为小于"41.4")。 - 经纬度列显示颠倒:表头的纬度/经度列与代码中输出的属性对应关系搞反了。
修正后的完整XSLT代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <!-- 使用key优化国家ID匹配效率 --> <xsl:key name="country-by-id" match="country" use="@id"/> <xsl:template match="/"> <html> <body> <h1 align="center">Mondial</h1> <table border="1"> <tr bgcolor="blue"> <th>Ciutat</th> <th>Latitud</th> <th>Longtitud</th> <th>Pais</th> </tr> <!-- 筛选纬度≥41.4的城市,转成数值比较 --> <xsl:for-each select="//city[number(@latitude) >= 41.4]"> <!-- 按所属国家名称降序排序 --> <xsl:sort select="key('country-by-id', @country)/name" order="descending"/> <!-- 按城市名称升序排序 --> <xsl:sort select="name"/> <tr> <td><xsl:value-of select="name"/></td> <td><xsl:value-of select="@latitude"/></td> <td><xsl:value-of select="@longitude"/></td> <!-- 通过key快速获取所属国家名称 --> <td><xsl:value-of select="key('country-by-id', @country)/name"/></td> </tr> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet>
关键优化点说明
- 使用
<xsl:key>提升匹配效率:定义country-by-id键后,通过key('country-by-id', @country)可以直接定位到当前城市所属的国家节点,避免遍历整个文档,数据量大时优势明显。 - 数值化纬度比较:用
number(@latitude) >= 41.4确保是数值逻辑比较,避免字符串排序的错误。 - 修正排序上下文:排序规则改为
key('country-by-id', @country)/name,确保按当前城市所属国家的名称降序排列。 - 调整经纬度显示顺序:让表头与输出的属性一一对应,修正显示颠倒的问题。
关于"无法在xsl:value-of的select中过滤"的问题
你完全可以在select属性中直接写过滤逻辑,比如:
- 只显示美国的城市名称:
name[key('country-by-id', @country)/name = 'USA'] - 过滤纬度大于50的城市:
name[number(../@latitude) > 50]
只要XPath表达式逻辑正确,就能在select中完成精准过滤。
内容的提问来源于stack exchange,提问作者alfredocabron
相关产品推荐
相关产品推荐

