如何用Python提取SDLXLIFF文件段属性并构建指定字典?
问题描述
我用Python读取SDLXLIFF格式文件(XLIFF变体),这类文件包含源文件副本和带翻译单元的body,翻译单元有source和target文本(称为segments)。想要生成如下格式的字典:
{1: ["人口は江戸末期まで概ね3000万人台で安定していたが。","At the end of the Edo period the population was stable at roughly 30 million people.","true"]}
其中键是seg-defs部分的segment id属性,值是对应mid匹配的seg-source文本、target文本,以及seg-defs中locked属性组成的三元列表。
我的实现思路:
- 遍历
seg-defs中的段元素 - 获取段的
id和locked属性 - 查找
seg-source中mid与id匹配的mrk元素,提取源文本 - 查找
target中mid与id匹配的mrk元素,提取目标文本 - 以
id为键,将三元列表作为值存入字典
遇到的问题:
- 无法遍历
seg-defs中的元素并提取id和locked属性 - 拿到
id后,不知道怎么筛选出mid匹配的mrk元素(比如id为1对应<mrk mtype="seg" mid="1">)
当前代码只能提取源和目标文本:
from lxml import etree my_file = "example.sdlxliff" f_xliff = open(my_file, encoding='utf-8', mode='r') xliff_input = ''.join(f_xliff.readlines()) tree = etree.fromstring(xliff_input) ns_map = dict() ns_map['x'] = tree.nsmap[None] for source, target in zip(tree.xpath('//x:seg-source//x:mrk', namespaces=ns_map), tree.xpath('//x:target//x:mrk', namespaces=ns_map)): print(source.text + " --- " + target.text + "\n")
seg的id和locked状态在文件中的位置:
<sdl:seg-defs> <sdl:seg id="1" locked="true" conf="Translated" origin="interactive">
解决方案
核心是处理SDLXLIFF的命名空间,以及通过XPath精准匹配元素。以下是高效且符合Python风格的实现:
from lxml import etree def parse_sdlxliff(file_path): # 读取并解析SDLXLIFF文件 tree = etree.parse(file_path) # 提取所有命名空间,兼容不同文件的前缀定义 ns_map = {} for prefix, uri in tree.getroot().nsmap.items(): ns_map[prefix or 'default'] = uri # 确保sdl命名空间被正确映射(部分文件可能自动省略前缀) ns_map['sdl'] = ns_map.get('sdl', 'http://sdl.com/FileTypes/SdlXliff/1.0') translation_dict = {} # 遍历seg-defs下的所有seg元素 for seg in tree.xpath('//sdl:seg-defs/sdl:seg', namespaces=ns_map): seg_id = int(seg.get('id')) locked_status = seg.get('locked', 'false') # 精准匹配对应mid的源文本mrk元素 source_mrk = tree.xpath(f'//default:seg-source/default:mrk[@mid="{seg_id}"]', namespaces=ns_map) source_text = source_mrk[0].text.strip() if source_mrk else '' # 精准匹配对应mid的目标文本mrk元素 target_mrk = tree.xpath(f'//default:target/default:mrk[@mid="{seg_id}"]', namespaces=ns_map) target_text = target_mrk[0].text.strip() if target_mrk else '' # 存入字典 translation_dict[seg_id] = [source_text, target_text, locked_status] return translation_dict # 使用示例 if __name__ == "__main__": result = parse_sdlxliff("example.sdlxliff") print(result)
关键说明
- 命名空间处理:SDLXLIFF包含默认命名空间和
sdl命名空间,必须在XPath中正确指定,否则无法定位到目标元素。 - 精准匹配:通过
@mid="{seg_id}"的XPath条件,直接关联seg的id和mrk的mid,避免了顺序匹配可能出现的错位问题。 - 健壮性优化:用
if source_mrk else ''处理元素不存在的情况,避免索引越界错误。 - 类型转换:将seg的
id转为整数,符合你期望的字典键类型。
内容的提问来源于stack exchange,提问作者SlowLearner
相关产品推荐
相关产品推荐

