在Python中使用LXML解析<p>标签

时间:2016-12-02 03:01:16

标签: python xpath lxml

我在Python 3.5中使用LXML解析TEI XML文件。出于某种原因,我不明白,解析器会在嵌套标签的任何地方打破<p>标签内容。

这是我的代码:

from lxml import etree
namespaces = {'tei':'http://www.tei-c.org/ns/1.0'}
xp_p = "//tei:body//tei:p//text()"
tree = etree.parse("data/sorb.xml")
paragraphs = tree.xpath(xp_p, namespaces=namespaces)
for par in paragraphs:
    print(par)

因此,例如,如果我在XML文件中有<p>,那么:

<p xml:id="b1d3qun-cdtvet">
  <lb ed="#S"/>Circa distinctionem 3m quaero utrum mens humana
  <lb ed="#S"/>sit <choice><orig>ymago</orig><reg>imago</reg></choice> trinitatis increatae <choice><orig>sicud</orig><reg>sicut</reg></choice> in rebus a<lb ed="#S"/>liis factis propter hominem est vestigium eiusdem tri<lb ed="#S"/>nitatis
</p>

我的脚本因此打破了它的内容:

Circa distinctionem 3m quaero utrum mens humana

sit 
ymago
imago
 trinitatis increatae 
sicud
sicut
 in rebus a
liis
                factis propter hominem est vestigium eiusdem tri
nitatis

而我正在努力获得整个<p>

Circa distinctionem 3m quaero utrum mens humana sit ymago imago trinitatis increatae sicud sicut in rebus a liis factis propter hominem est vestigium eiusdem tri nitatis

第1部分我的问题是,发生了什么,我该如何解决我的问题?

我的问题是

第2部分,我怎样才能得到其他结果?

Circa distinguishedem 3m quaero utrum mens humana sit ymagoimago trinitatis increatae sicudsicut in rebus aliis factis propter hominem est vestigium eiusdem trinitatis

(即<p>)的全部内容?

1 个答案:

答案 0 :(得分:3)

  

我的问题的第一部分是,发生了什么,我该如何解决我的问题?

您的xpath表达式明确请求文本节点:

 //tei:body//tei:p//text()

所以你得到的是<p>元素中包含的文本节点列表。

  

我的问题的第2部分是,我怎样才能得到这个其他结果?

您可能希望迭代<p>元素本身,而不是文本节点:

xp_p = "//tei:body//tei:p"

然后在循环中使用xpath string函数:

for par in paragraphs:
  text = par.xpath('string(.)')

哪会给你:

'\n  Circa distinctionem 3m quaero utrum mens humana\n  sit ymagoimago trinitatis increatae sicudsicut in rebus aliis factis propter hominem est vestigium eiusdem trinitatis\n'

你可以得到类似的结果:

text = ' '.join(x.strip() for x in par.xpath('.//text()'))

...这将有利于将所有换行符转换为空格,因此最终会得到:

' Circa distinctionem 3m quaero utrum mens humana sit ymago imago trinitatis increatae sicud sicut in rebus a liis factis propter hominem est vestigium eiusdem tri nitatis'

如果您希望整个HTML内容包含在<p>元素中,而不是文本,请参阅this answer。解决方案看起来像这样:

innerhtml = ''.join(etree.tostring(child) for child in par.iterdescendants())

结果如下:

'<lb xmlns="http://www.tei-c.org/ns/1.0" ed="#S"/>Circa distinctionem 3m quaero utrum mens humana\n  <lb xmlns="http://www.tei-c.org/ns/1.0" ed="#S"/>sit <choice xmlns="http://www.tei-c.org/ns/1.0"><orig>ymago</orig><reg>imago</reg></choice> trinitatis increatae <orig xmlns="http://www.tei-c.org/ns/1.0">ymago</orig><reg xmlns="http://www.tei-c.org/ns/1.0">imago</reg><choice xmlns="http://www.tei-c.org/ns/1.0"><orig>sicud</orig><reg>sicut</reg></choice> in rebus a<orig xmlns="http://www.tei-c.org/ns/1.0">sicud</orig><reg xmlns="http://www.tei-c.org/ns/1.0">sicut</reg><lb xmlns="http://www.tei-c.org/ns/1.0" ed="#S"/>liis factis propter hominem est vestigium eiusdem tri<lb xmlns="http://www.tei-c.org/ns/1.0" ed="#S"/>nitatis\n'