如何在lxml xpath text()函数中控制换行处理?

2024-06-25 22:59:16 发布

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

从fedora17切换到18后,对于相同的lxml代码,我得到了不同的解析行为,这显然是由于底层库的不同版本(libxml2和libxslt版本发生了变化)。在

下面是一个lxml代码的示例,两个版本的结果不同:

from io import BytesIO
from lxml import etree

myHtmlString = \
    '<!doctype html public "-//w3c//dtd html 4.0 transitional//en">\r\n'+\
    '<html>\r\n'+\
    '<head>\r\n'+\
    '   <title>Title</title>\r\n'+\
    '</head>\r\n'+\
    '<body/>\r\n'+\
    '</html>\r\n'
myFile = BytesIO(myHtmlString)
myTree = etree.parse(myFile, etree.HTMLParser())
myTextElements = myTree.xpath("//text()")
myFullText = ''.join([myEl for myEl in myTextElements])

assert myFullText == 'Title', repr(myFullText)

f17版本传递assert,即xpath("//text()")只返回文本'Title',而f18版本的输出失败

^{pr2}$

显然,f18版本处理换行符和空白与f17版本不同。在

有没有办法控制这种行为?(某个地方的可选论点?) 或者更好的是,有没有一种方法可以让我使用新的库恢复旧的行为?在


Tags: 代码fromimport版本titlehtmlmyfilelxml
1条回答
网友
1楼 · 发布于 2024-06-25 22:59:16

在XML中,text()按原样返回标记中的文本(未压缩),因此如果您有任何空白字符、制表符和新行,它们将包括在内。在

可能是使用+和\n\r构造多行字符串的方式意外地测试了两个不同的字符串。在

如果您像下面的示例一样将字符串更改为三引号字符串并进行测试。在

from io import BytesIO
from lxml import etree


html = '''
    <!doctype html public "-//w3c//dtd html 4.0 transitional//en">
    <html>
    <head>
       <title>Title</title>
    </head>
    <body/>
    </html>
'''
tree = etree.parse(BytesIO(html), etree.HTMLParser())
text_elements = tree.xpath("//text()")
full_text = ''.join(text_elements)
assert full_text == 'Title', repr(full_text)

您还可以看到用空格或新行包围文本使它们成为text()函数返回的一部分。请参阅下面的title。在

^{pr2}$

如果不需要空格,您可以自己调用字符串上的strip()。如果您确定即使您的标记不包含空格,您也应该在lxml mailing list上报告该错误。在

相关问题 更多 >