如何使用XSLT 3.0根据TextStyle属性替换String的CONTENT值
XSLT 3.0 实现样式关联的文本包裹方案
核心思路
通过建立TextStyle与String的ID关联,筛选出带有指定FONTSTYLE属性的样式节点,将对应String的CONTENT值用匹配的样式标签包裹。
输入XML示例
假设你的源文件结构如下:
<Root> <TextStyles> <TextStyle ID="TS1" FONTSTYLE="bold"/> <TextStyle ID="TS2" FONTSTYLE="italic"/> <TextStyle ID="TS3"/> <!-- 无指定样式,不处理 --> </TextStyles> <Strings> <String ID="TS1" CONTENT="Human"/> <String ID="TS2" CONTENT="Hello World"/> <String ID="TS3" CONTENT="Plain Text"/> </Strings> </Root>
实现XSLT 3.0代码
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 默认复制所有未匹配的节点,减少冗余代码 --> <xsl:mode on-no-match="shallow-copy"/> <!-- 建立索引:仅关联带FONTSTYLE属性的TextStyle,通过ID匹配 --> <xsl:key name="style-map" match="TextStyle[@FONTSTYLE]" use="@ID"/> <!-- 处理符合条件的String节点 --> <xsl:template match="String[key('style-map', @ID)]"> <xsl:copy> <!-- 保留原节点除CONTENT外的所有属性 --> <xsl:copy-of select="@* except @CONTENT"/> <!-- 获取对应样式名称 --> <xsl:variable name="target-style" select="key('style-map', @ID)/@FONTSTYLE"/> <!-- 生成包裹后的CONTENT属性 --> <xsl:attribute name="CONTENT"> <xsl:value-of select="concat('<', $target-style, '>', @CONTENT, '</', $target-style, '>')"/> </xsl:attribute> </xsl:copy> </xsl:template> </xsl:stylesheet>
关键细节说明
<xsl:mode on-no-match="shallow-copy"/>:XSLT 3.0特性,自动复制所有未被模板匹配的节点,无需手动编写大量复制逻辑。- 索引优化:用
<xsl:key>建立ID到样式的映射,比直接遍历查找效率高,适合处理大体积XML文件。 - 精准匹配:仅处理存在对应带样式TextStyle的String节点,避免无效操作。
- 样式标签生成:通过
concat拼接转义后的尖括号,确保生成的CONTENT值符合XML属性规范。
输出结果示例
处理后对应的String节点CONTENT会被样式标签包裹:
<Root> <TextStyles> <TextStyle ID="TS1" FONTSTYLE="bold"/> <TextStyle ID="TS2" FONTSTYLE="italic"/> <TextStyle ID="TS3"/> </TextStyles> <Strings> <String ID="TS1" CONTENT="<bold>Human</bold>"/> <String ID="TS2" CONTENT="<italic>Hello World</italic>"/> <String ID="TS3" CONTENT="Plain Text"/> </Strings> </Root>
自定义筛选特定样式
如果只需要处理某一种样式(比如仅bold),只需修改索引的匹配条件:
<xsl:key name="style-map" match="TextStyle[@FONTSTYLE='bold']" use="@ID"/>
内容的提问来源于stack exchange,提问作者Balaji
相关产品推荐
相关产品推荐

