You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 02:10:52