使用XSL拆分双列HTML表格为XML时,如何正确处理item标签拆分?
解决方案
不要尝试通过输出原始标签字符串来拆分节点,XSL是基于节点树的转换工具,直接构造两个独立的<item>节点即可,完全规避标签拼接的问题。
核心实现思路
遍历表格的每一行,对每行的前4个<td>生成第一个<item>,后4个<td>生成第二个<item>,不需要在列处理中插入闭合/开启标签。
基础版XSL代码示例
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <!-- 匹配根节点,输出XML根元素 --> <xsl:template match="/"> <items> <xsl:apply-templates select="//tr"/> </items> </xsl:template> <!-- 处理每一行表格,生成两个item节点 --> <xsl:template match="tr"> <!-- 第一个item:对应前4列数据 --> <item> <product><xsl:value-of select="td[1]"/></product> <price><xsl:value-of select="td[2]"/></price> <order_number><xsl:value-of select="td[3]"/></order_number> <amount><xsl:value-of select="td[4]"/></amount> </item> <!-- 第二个item:对应后4列数据 --> <item> <product><xsl:value-of select="td[5]"/></product> <price><xsl:value-of select="td[6]"/></price> <order_number><xsl:value-of select="td[7]"/></order_number> <amount><xsl:value-of select="td[8]"/></amount> </item> </xsl:template> </xsl:stylesheet>
问题根源说明
- 输出转义的
</item><item>时,XSL会将其视为普通文本节点,不会解析成XML标签,所以会原样显示。 - 直接输出未转义的
</item><item>会破坏XSL的节点树构造逻辑——XSL转换时会严格检查输出节点的结构完整性,中途插入闭合/开启标签会导致节点树不合法,触发解析错误。
逐列处理场景的兼容方案
如果你的XSL原本是按列遍历处理的,可通过判断列的位置来拆分节点:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> <items> <xsl:apply-templates select="//tr"/> </items> </xsl:template> <xsl:template match="tr"> <!-- 生成第一个item,处理前4列 --> <item> <xsl:apply-templates select="td[position() <=4]"/> </item> <!-- 生成第二个item,处理后4列 --> <item> <xsl:apply-templates select="td[position() >4]"/> </item> </xsl:template> <!-- 前4列对应第一个item的子节点 --> <xsl:template match="td[position()=1]"> <product><xsl:value-of select="."/></product> </xsl:template> <xsl:template match="td[position()=2]"> <price><xsl:value-of select="."/></price> </xsl:template> <xsl:template match="td[position()=3]"> <order_number><xsl:value-of select="."/></order_number> </xsl:template> <xsl:template match="td[position()=4]"> <amount><xsl:value-of select="."/></amount> </xsl:template> <!-- 后4列对应第二个item的子节点 --> <xsl:template match="td[position()=5]"> <product><xsl:value-of select="."/></product> </xsl:template> <xsl:template match="td[position()=6]"> <price><xsl:value-of select="."/></price> </xsl:template> <xsl:template match="td[position()=7]"> <order_number><xsl:value-of select="."/></order_number> </xsl:template> <xsl:template match="td[position()=8]"> <amount><xsl:value-of select="."/></amount> </xsl:template> </xsl:stylesheet>
内容的提问来源于stack exchange,提问作者U. Windl
相关产品推荐
相关产品推荐

