Как остановить lxml от создания html-сущностей при написании документов utf-8 - PullRequest
0 голосов
/ 11 января 2019

Мне нужно обработать XML-файлы, содержащие текст с румынскими символами (текст, подобный 'licenţe şi mărci').

После обработки этот текст попадает в HTML-документы. Если на последнем этапе я вывожу содержимое, используя что-то вроде:

doc.write(path, encoding='utf-8', method='xml' )

ПРИМЕЧАНИЕ : doc выше - это экземпляр lxml.etree.ElementTree

Я получаю что-то вроде:

<span id="123">licenţe şi mărci</span>

Все выглядит хорошо (т. Е. Румынские символы не преобразуются в HTML-объекты).

Если я использую метод кодирования html

doc.write(path, encoding='utf-8', method='html' )

Я получаю что-то вроде:

<span id="128927">licen&#355;e &#351;i m&#259;rci</span>

Хотя документ в браузере выглядит нормально, текст в документе также используется другим процессом, который извлекает текст и использует его для некоторых различных заданий, которые полностью запутываются html-сущностями.

Хотя использование xml в качестве аргумента метода для etree.ElementTree.write, похоже, решает мою текущую проблему, это неправильно, так как я действительно хочу генерировать html файлы и может плохо работать в других контекстах.

Есть ли способ написать документ в формате html (используя method='html') без замены lxml символов не ascii на html-сущности?


После вопроса @mzjn выясняется, что история немного сложнее.

Вот минимальный код, который воспроизводит проблему:

from lxml import etree
from os import path

def process( method, out_name ):

    # the doc
    x = etree.XML('<span id="123">licenţe şi mărci</span>')
    tree = etree.ElementTree(x)

    #do some processing
    modifiedTree = modifyDoc(tree)

    # write the result
    modifiedTree.write(out_name, encoding='utf-8',  method=method)

def modifyDoc(tree):
    root = tree.getroot()

    doNothingTransformPath = _absolutePath('transform.xslt')
    transform_doc = etree.parse(doNothingTransformPath)
    transform = etree.XSLT(transform_doc)
    return transform(root)

def _absolutePath(relative):
    return path.abspath(path.join( __file__ , '..', relative))

if __name__ == '__main__':
    process( 'xml', 'out1.xml')
    process( 'html', 'out2.html')

где (в этом примере) XSLT-преобразование (ничего не делая):

- transform.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" indent="no"/>
    <xsl:template match="/">
        <xsl:copy-of select="/"/>
    </xsl:template>
</xsl:stylesheet>

Если я не пропущу документ через XSLT-преобразование, выходные данные не содержат HTML-сущности, при передаче через функцию modifyDoc (т. Е. С применением преобразования xslt) выходные данные изменяются, как описано выше, (т.е. при использовании method='html' вывод содержит HTML-сущности).

Запустив программу выше, выдает два файла:

- out1.xml -

<span id="123">licenţe şi mărci</span>

и - out2.html -

<span id="123">licen&#x163;e &#x15F;i m&#x103;rci</span>
...