多层<xsl:for-each>循环元素无法在表格显示,XML数据为空单元格求助
解决XML数据表格空单元格与多层xsl:for-each失效问题
我来帮你搞定这个XML+XSLT渲染表格的坑——空单元格和多层循环失效多半是XPath路径踩了坑,或者上下文节点没搞清楚,咱们一步步捋:
1. 先排查最常见的XPath上下文错误
多层<xsl:for-each>会切换当前节点的上下文,这很容易踩坑:
- 比如你在第一层循环
select="cursos/curso"之后,当前上下文就变成了<curso>节点;如果这时候要遍历它下面的<tema>,得用相对路径programa/temas/tema,而不是从头写/cursos/curso/programa/temas/tema(除非你特意用绝对路径)。 - 空单元格大概率是你引用节点时路径错了:比如在
<tema>的循环里直接写nombreCurso,这时候上下文是<tema>,根本找不到父节点的<nombreCurso>,自然显示为空。
适配你XML结构的正确示例XSLT
<?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> <table border="1"> <tr> <th>课程编码</th> <th>课程名称</th> <th>主题编码</th> <th>主题标题</th> </tr> <!-- 第一层:遍历所有课程 --> <xsl:for-each select="cursos/curso"> <!-- 保存当前课程节点的引用,避免上下文切换后找不到 --> <xsl:variable name="currentCourse" select="."/> <!-- 第二层:遍历当前课程下的所有主题 --> <xsl:for-each select="programa/temas/tema"> <tr> <!-- 用变量引用上层课程的属性和元素 --> <td><xsl:value-of select="$currentCourse/@codigoCurso"/></td> <td><xsl:value-of select="$currentCourse/nombreCurso"/></td> <td><xsl:value-of select="@codigoTema"/></td> <td><xsl:value-of select="tituloTema"/></td> </tr> </xsl:for-each> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet>
2. 其他可能的原因
- XML格式不完整:你给的XML片段里
<tituloTema>Introduccion</tituloTema...明显没写完,缺失闭合标签会导致解析器无法正确识别节点,直接造成空内容,先确保XML是完全闭合的。 - DTD验证问题:你的XML引用了
cursos.dtd,如果DTD里定义的元素结构(比如嵌套关系、必填属性)和实际XML不匹配,解析器可能会忽略不符合规则的节点,导致渲染为空。可以先临时去掉DOCTYPE声明,测试是否能正常显示,来排查是否是DTD的锅。 - 命名空间问题:如果你的完整XML里有
xmlns命名空间属性,XSLT里必须声明对应的前缀,否则XPath会匹配不到任何节点(比如<xsl:stylesheet ... xmlns:my="http://xxx">,然后用my:curso来匹配)。
快速排查步骤
- 先写一个极简版XSLT:只渲染第一层
<curso>的信息,确认能正常显示课程编码和名称,排除基础路径问题。 - 再逐步添加第二层
<tema>的循环,每一步测试渲染结果,定位是哪一层出了问题。 - 用XML编辑器或浏览器控制台的XPath测试功能,把你的XPath路径贴进去,验证是否能匹配到目标节点。
内容的提问来源于stack exchange,提问作者Ariwake
相关产品推荐
相关产品推荐

