使用XSLT处理XML中的命名空间问题
问题分析与解决
需求与问题
需要从screen.xml中提取所有tc:field标签的category和name属性,生成指定格式的HTML输出,但现有XSLT无法匹配目标节点,仅输出空的<ul>。
原XML文件(screen.xml)
<tc:transform xmlns:tc="http://www.w2.prg/1999/XSL/Transform" version="1.0"> <tc:blockTemplate blockTitle="Court/Agency"> <link flush="true" href="./customimages/customBlockStylesheet.css" rel="stylesheet" type="text/css"/> <!-- BEGIN Court Information Content --> <table border="0" cellpadding="0" cellspacing="0" width="100%"> <!-- Control Row --> <tr> <td class="altFieldColor" height="0" width="20%"/> <td class="altFieldColor" height="0" width="10"/> <td class="altFieldColor" height="0" width="25%"/> <td class="altFieldColor" height="0" width="2"/> <td class="altFieldColor" height="0" width="10"/> <td class="altFieldColor" height="0" width="20%"/> <td class="altFieldColor" height="0" width="10"/> <td class="altFieldColor" height="0" width="100%"/> </tr> <tr> <td colspan="8"> <img border="0" height="2" src="./customimages/spacer.gif" width="1"/> </td> </tr> <tr> <td class="altFieldColor" height="40"> <tc:label category="DISP" name="CoreDocketNumber"/>:</td> <td class="altFieldColor" width="10"> <img border="0" height="1" src="./customimages/spacer.gif" width="10"/> </td> <td class="altFieldColor" nowrap="true"> **<tc:field category="DISP" name="CoreDocketNumber"/>** </td> <td width="2"> <img border="0" height="1" src="./customimages/spacer.gif" width="2"/> </td> <td class="altFieldColor" width="10"> <img border="0" height="1" src="./customimages/spacer.gif" width="10"/> </td> <td class="altFieldColor" height="40"> <tc:label category="DISP" name="CoreCourt"/>:</td> <td class="altFieldColor" width="10"> <img border="0" height="1" src="./customimages/spacer.gif" width="10"/> </td> <td class="altFieldColor" nowrap="true"> **<tc:field category="DISP" name="CoreCourt"/>** </td> </tr> </table> <!-- END Court Information Content --> </tc:blockTemplate> </tc:transform>
期望输出
<H1>screen.xml</H1> <ul> <li>DISP.CoreDocketNumber</li> <li>DISP.CoreCourt</li> </ul>
尝试的XSLT(无效)
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tc="http://www/w2.prg/1999/XSL/Tansform" xmlns="http://www.w3.org/1999/xhtml"> <xsl:output method="html" indent="yes"/> <xsl:template match="@*|node()"> <ul> <xsl:apply-templates select="tc:field"/> </ul> </xsl:template> <xsl:template match="tc:field"> <li><xsl:value-of select="@category"/>.<xsl:value-of select="@name"/></li> </xsl:template> </xsl:stylesheet>
错误输出
<ul xmlns:tc="http://www/w2.prg/1999/XSL/Tansform" xmlns="http://www.w3.org/1999/xhtml"></ul>
问题修复
1. 修正命名空间
原XML中tc的命名空间是http://www.w2.prg/1999/XSL/Transform,但尝试的XSLT存在两处拼写错误:
www后误写为斜杠/,正确应为点.Transform误写为Tansform
命名空间必须完全一致才能匹配节点。
2. 调整模板逻辑
默认模板match="@*|node()"不能直接输出<ul>,否则会匹配所有节点并重复输出ul,且没有递归遍历子节点查找tc:field。正确做法是:
- 写一个根节点模板,负责输出标题和ul容器
- 默认模板仅递归处理子节点,同时忽略不需要的文本节点(如空格、注释)
修正后的XSLT
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tc="http://www.w2.prg/1999/XSL/Transform"> <!-- 输出HTML格式,关闭默认命名空间输出 --> <xsl:output method="html" indent="yes" omit-xml-declaration="yes"/> <!-- 匹配根节点,输出标题和ul容器 --> <xsl:template match="/"> <H1>screen.xml</H1> <ul> <!-- 递归遍历所有节点,查找tc:field --> <xsl:apply-templates select="//tc:field"/> </ul> </xsl:template> <!-- 匹配tc:field节点,输出li项 --> <xsl:template match="tc:field"> <li><xsl:value-of select="@category"/>.<xsl:value-of select="@name"/></li> </xsl:template> <!-- 忽略不需要的节点:注释、文本节点(空格等) --> <xsl:template match="comment()|text()[normalize-space()='']"/> <!-- 默认模板:递归处理其他元素节点,不输出内容 --> <xsl:template match="*"> <xsl:apply-templates/> </xsl:template> </xsl:stylesheet>
正确输出
<H1>screen.xml</H1> <ul> <li>DISP.CoreDocketNumber</li> <li>DISP.CoreCourt</li> </ul>
内容的提问来源于stack exchange,提问作者user2890372
相关产品推荐
相关产品推荐

