如何使用XSLT实现元素转换与HTML标签映射(查找替换)
实现方案:将ALTO XML中的元素转换为HTML格式化文本
需求说明
需要通过XSLT完成以下转换:
- 移除XML中的
<String>元素,根据其STYLEREFS属性关联的TextStyle样式,生成对应的HTML格式化元素 - 样式与HTML标签的映射规则:
bold→<b>sup→<sup>- 无特殊样式的文本直接输出内容
输入XML
<?xml version="1.0" encoding="UTF-8"?> <ALTO> <STYLES> <TextStyle ID="font1" FONTFAMILY="cambria" FONTSIZE="12.000" FONTSTYLE="bold"/> <TextStyle ID="font2" FONTFAMILY="cambria" FONTSIZE="7.920" FONTSTYLE="sup"/> <TextStyle ID="font3" FONTFAMILY="cambria" FONTSIZE="12.000" FONTSTYLE="it"/> </STYLES> <LAYOUT> <TextBlock ID="p1_b1" HPOS="83.6703" VPOS="75.8759" HEIGHT="10.6680" WIDTH="445.700"> <TextLine WIDTH="445.700" HEIGHT="10.6680" ID="p1_t1" HPOS="83.6703" VPOS="75.8759"> <String ID="p1_w1" CONTENT="Hie" HPOS="83.6703" VPOS="75.8759" STYLEREFS="font0"/> <String ID="p1_w2" CONTENT="org" HPOS="154.915" VPOS="75.8759" STYLEREFS="font0"/> <String ID="p1_w3" CONTENT="of" HPOS="228.005" VPOS="75.8759" STYLEREFS="font0"/> <String ID="p1_w4" CONTENT="the" HPOS="241.393" VPOS="75.8759" STYLEREFS="font0"/> <String ID="p1_w5" CONTENT="Human" HPOS="261.948" VPOS="75.8759" STYLEREFS="font1"/> <String ID="p1_w6" CONTENT="cell" HPOS="303.263" VPOS="75.8759" STYLEREFS="font0"/> <String ID="p1_w8" CONTENT="a" HPOS="354.900" VPOS="75.8759" STYLEREFS="font0"/> <String ID="p1_w9" CONTENT="CANCER" HPOS="363.965" VPOS="75.8759" STYLEREFS="font3"/> </TextLine> </TextBlock> </LAYOUT> </ALTO>
现有XSLT问题分析
原代码存在以下问题:
- 重复定义了匹配
/|node()|*|@*的模板,导致模板优先级冲突 - 定义的
styletag1/styletag2/styletag3参数未实际使用 - 错误地尝试在
CONTENT属性中拼接HTML标签文本,而非直接生成HTML元素 text-style键的匹配目标错误,未正确关联样式ID与样式类型
修正后的XSLT代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="#all" version="3.0"> <!-- 输出配置:生成XHTML,缩进格式化 --> <xsl:output method="xhtml" indent="yes" encoding="UTF-8"/> <!-- 定义键:通过样式ID查找对应的TextStyle元素 --> <xsl:key name="text-style" match="TextStyle" use="@ID"/> <!-- 默认模板:复制所有未匹配的节点(保留结构,除了String元素) --> <xsl:mode on-no-match="shallow-copy"/> <!-- 匹配STYLES元素:不需要保留,直接跳过 --> <xsl:template match="STYLES"/> <!-- 匹配String元素:根据样式生成对应HTML元素 --> <xsl:template match="String"> <!-- 获取关联的样式信息 --> <xsl:variable name="style" select="key('text-style', @STYLEREFS)"/> <!-- 根据样式类型选择输出标签 --> <xsl:choose> <xsl:when test="$style/@FONTSTYLE = 'bold'"> <b><xsl:value-of select="@CONTENT"/></b> </xsl:when> <xsl:when test="$style/@FONTSTYLE = 'sup'"> <sup><xsl:value-of select="@CONTENT"/></sup> </xsl:when> <xsl:when test="$style/@FONTSTYLE = 'it'"> <i><xsl:value-of select="@CONTENT"/></i> </xsl:when> <!-- 无匹配样式或无关联样式时直接输出文本 --> <xsl:otherwise> <xsl:value-of select="@CONTENT"/> </xsl:otherwise> </xsl:choose> <!-- 添加空格,保证单词间的分隔 --> <xsl:text> </xsl:text> </xsl:template> </xsl:stylesheet>
转换输出结果
<?xml version="1.0" encoding="UTF-8"?> <ALTO> <LAYOUT> <TextBlock ID="p1_b1" HPOS="83.6703" VPOS="75.8759" HEIGHT="10.6680" WIDTH="445.700"> <TextLine WIDTH="445.700" HEIGHT="10.6680" ID="p1_t1" HPOS="83.6703" VPOS="75.8759"> Hie org of the <b>Human</b> cell a <i>CANCER</i> </TextLine> </TextBlock> </LAYOUT> </ALTO>
内容的提问来源于stack exchange,提问作者Balaji
相关产品推荐
相关产品推荐

