求助:使用XSLT document()函数实现XML文本翻译(Notepad++)
XSLT 1.0实现XML文本翻译替换的正确方案
需求说明
使用Notepad++和XSLT 1.0,将Data.xml中所有带@ID属性的元素(包括Textabschnitt和嵌套的Root元素)的文本内容,替换为Dict.xml中对应id属性的uicontrol元素的翻译文本,保持原XML结构不变。
现有文件内容
Data.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Root> <Textabschnitt> <Root ID="2050775654055586328">Administration</Root> </Textabschnitt> <Textabschnitt ID="13667714361645396460">All</Textabschnitt> <Textabschnitt ID="4765748458590838957">Application</Textabschnitt> <Textabschnitt> <Tabelle> <Zelle> <Textabschnitt ID="14682159838120944212">Name</Textabschnitt> </Zelle> <Zelle> <Textabschnitt ID="2960145709916589219">Status</Textabschnitt> </Zelle> </Tabelle> </Textabschnitt> </Root>
Dict.xml
<?xml version="1.0" encoding="utf-8"?> <DICT> <DICT_ENTRY LANG_ID="ro"> <uicontrol id="2050775654055586328">Administrare</uicontrol> </DICT_ENTRY> <DICT_ENTRY LANG_ID="ro-RO"> <uicontrol id="13667714361645396460">Toate</uicontrol> </DICT_ENTRY> <DICT_ENTRY LANG_ID="ro-RO"> <uicontrol id="4765748458590838957">Aplicație</uicontrol> </DICT_ENTRY> <DICT_ENTRY LANG_ID="ro-RO"> <uicontrol id="14682159838120944212">Nume</uicontrol> </DICT_ENTRY> <DICT_ENTRY LANG_ID="ro-RO"> <uicontrol id="2960145709916589219">Stare</uicontrol> </DICT_ENTRY> </DICT>
原代码的问题分析
你提供的XSLT代码存在几个关键错误:
- 版本不匹配:实际使用XSLT 1.0,但代码声明为
version="2.0",部分XSLT处理器(包括Notepad++默认使用的)会因此报错或无法正常执行。 - 模板匹配错误:模板匹配所有
@ID属性,但在属性模板中输出文本内容不符合XSLT规范——属性模板只能生成属性,不能直接输出节点文本,这会导致结构混乱甚至输出空白。 - 命名空间冗余:引入了
fo、xs、fn等未使用的命名空间,可能干扰处理器解析。
修正后的XSLT代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" standalone="yes"/> <!-- 加载字典文件 --> <xsl:variable name="dict" select="document('Dict.xml')"/> <!-- 为字典中的uicontrol建立id索引,提升查找效率 --> <xsl:key name="trans-key" match="uicontrol" use="@id"/> <!-- 身份模板:默认复制所有节点和属性 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 替换带ID的Textabschnitt元素的文本内容 --> <xsl:template match="Textabschnitt[@ID]/text()"> <xsl:value-of select="key('trans-key', ../@ID, $dict)"/> </xsl:template> <!-- 替换嵌套在Textabschnitt中的带ID的Root元素的文本内容 --> <xsl:template match="Textabschnitt/Root[@ID]/text()"> <xsl:value-of select="key('trans-key', ../@ID, $dict)"/> </xsl:template> </xsl:stylesheet>
关键修正说明
- 版本调整:将
stylesheet的version改为1.0,匹配实际使用环境。 - 索引优化:使用
<xsl:key>为字典中的翻译项建立索引,相比直接路径查找,XSLT处理器能更快定位到对应翻译。 - 正确的模板匹配:匹配目标元素的文本节点,直接替换为对应翻译,既保留原元素的属性和结构,又替换内容。
- 路径处理:确保
Dict.xml与Data.xml、XSL文件在同一目录下,document()函数才能正确加载文件。
期望输出结果
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Root> <Textabschnitt> <Root ID="2050775654055586328">Administrare</Root> </Textabschnitt> <Textabschnitt ID="13667714361645396460">Toate</Textabschnitt> <Textabschnitt ID="4765748458590838957">Aplicație</Textabschnitt> <Textabschnitt> <Tabelle> <Zelle> <Textabschnitt ID="14682159838120944212">Nume</Textabschnitt> </Zelle> <Zelle> <Textabschnitt ID="2960145709916589219">Stare</Textabschnitt> </Zelle> </Tabelle> </Textabschnitt> </Root>
内容的提问来源于stack exchange,提问作者user24000
相关产品推荐
相关产品推荐

