使用BeautifulSoup转换XLIFF文件

2024-06-17 14:58:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用BeautifulSoup和googletrans软件包翻译Xliff文件。我设法提取所有字符串并翻译它们,并设法用翻译创建新标记来替换字符串,例如

<trans-unit id="100890::53706_004">
<source>Continue in store</source>
<target>Kontynuuj w sklepie</target>
</trans-unit>

当源标记中有其他标记时,问题就会出现

例如

<source><x ctype="x-htmltag" equiv-text="&lt;b&gt;" id="html_tag_191"/>Choose your product\
<x ctype="x-htmltag" equiv-text="&lt;/b&gt;" id="html_tag_192"/>From a list: </source>

这些标记的数量不同,字符串出现的顺序也不同。例如<source> text1 <x /> <x/> text2 <x/> text3 </source>。每个x标记都是唯一的,具有不同的id和属性

有没有一种方法可以在不创建新标记的情况下修改标记内的文本? 我想我可以提取x标记及其属性,但是不同代码行中的顺序或字符串和x标记有很大的不同,我不知道怎么做。 也许还有其他软件包更适合翻译xliff文件


Tags: 文件字符串text标记ltgtidsource
3条回答

要从<source>中提取两个文本条目,可以使用以下方法:

from bs4 import BeautifulSoup
import requests

html = """<source><x ctype="x-htmltag" equiv-text="&lt;b&gt;" id="html_tag_191"/>Choose your product\
<x ctype="x-htmltag" equiv-text="&lt;/b&gt;" id="html_tag_192"/>From a list: </source>"""

soup = BeautifulSoup(html, 'lxml')
print(list(soup.source.stripped_strings))

给你:

['Choose your product', 'From a list:']

我建议不要使用通用XML解析器解析XLIFF文件。相反,尝试寻找一个专门的XLIFF工具包。有一些python项目,但我没有使用它们的经验(我:主要是Java)

您可以使用for-loop处理source中的所有子项。
你可以用copy.copy(child)appendtarget复制它们。
同时,您可以检查child是否为NavigableString并将其转换


text = '''<source><x ctype="x-htmltag" equiv-text="&lt;b&gt;" id="html_tag_191"/>Choose your product\
<x ctype="x-htmltag" equiv-text="&lt;/b&gt;" id="html_tag_192"/>From a list: </source>'''

conversions = {
    'Choose your product': 'Wybierz swój produkt',
    'From a list: ': 'Z listy: ',
}

from bs4 import BeautifulSoup as BS
from bs4.element import NavigableString
import copy

#soup = BS(text, 'html.parser')  # it has problem to parse it
#soup = BS(text, 'html5lib')     # it has problem to parse it
soup = BS(text, 'lxml')

# create `<target>`
target = soup.new_tag('target')

# add `<target>` after `<source>
source = soup.find('source')
source.insert_after('', target)

# work with children in `<source>`
for child in source:
    print('type:', type(child))

    # duplicate child and add to `<target>`
    child = copy.copy(child)
    target.append(child)

    # convert text and replace in child in `<target>`        
    if isinstance(child, NavigableString):
        new_text = conversions[child.string]
        child.string.replace_with(new_text)

print(' - target  -')
print(target)
print(' - source  -')
print(source)
print(' - soup  -')
print(soup)

结果(为使其更具可读性,几乎没有重新格式化):

type: <class 'bs4.element.Tag'>
type: <class 'bs4.element.NavigableString'>
type: <class 'bs4.element.Tag'>
type: <class 'bs4.element.NavigableString'>

 - target  -

<target>
  <x ctype="x-htmltag" equiv-text="&lt;b&gt;" id="html_tag_191"></x>
  Wybierz swój produkt
  <x ctype="x-htmltag" equiv-text="&lt;/b&gt;" id="html_tag_192"></x>
  Z listy: 
</target>

 - source  -

<source>
  <x ctype="x-htmltag" equiv-text="&lt;b&gt;" id="html_tag_191"></x>
  Choose your product
  <x ctype="x-htmltag" equiv-text="&lt;/b&gt;" id="html_tag_192"></x>
  From a list: 
</source>

 - soup  -

<html><body>
<source>
  <x ctype="x-htmltag" equiv-text="&lt;b&gt;" id="html_tag_191"></x>
  Choose your product
  <x ctype="x-htmltag" equiv-text="&lt;/b&gt;" id="html_tag_192"></x>
  From a list: 
</source>
<target>
  <x ctype="x-htmltag" equiv-text="&lt;b&gt;" id="html_tag_191"></x>
  Wybierz swój produkt
  <x ctype="x-htmltag" equiv-text="&lt;/b&gt;" id="html_tag_192"></x>
  Z listy: 
</target>
</body></html>

相关问题 更多 >