python - 找出 CDATA 在 lxml 元素中的位置?

标签 python xml lxml cdata

我需要解析和重建解析器使用的文件格式,该文件格式使用的语言只能被描述为 XML。我意识到符合标准的 XML 既不关心 CDATA 也不关心空格,但不幸的是,这个应用程序要求我关心两者......

我正在使用 lxml.etree因为它非常擅长保存 CDATA。

例如:

s = '''
<root>
  <item>
     <![CDATA[whatever]]>
  </item>
</root>'''

import lxml.etree as et
et.fromstring(s, et.XMLParser(strip_cdata=False))
item = root.find('item')
print et.tostring(item)

这打印:

<item>
    <![CDATA[whatever]]>
  </item>

lxml完全保留了 <item> 的格式标记...太棒了!

问题是我没有任何方法可以准确判断 CDATA 在标签文本中的开始和结束位置。属性(property)item.text没有说明文本的哪一部分被包裹在 CDATA 中:

item.text
 ==> '\n     whatever\n  '

因此,如果我修改它,并尝试将其作为 CDATA 吐出,那么我将丢失空白的位置:

item.text = CDATA('foobar')
et.tostring(item)
 ==> '<item><![CDATA[foobar]]></item>\n'

很明显,lxml “知道”CDATA 在节点文本中的位置,因为它用 node.tostring() 保存它.但是,我想不出一种方法来反省文本的哪些部分是 CDATA,哪些不是。 有什么建议吗?

最佳答案

我不确定 lxml,但是使用 minidom 您可以更改 CDATA 部分并保留周围的空白,如 CDATASection是一个单独的节点类型。

>>> from xml.dom import minidom
>>> data = minidom.parseString(s)
>>> parts = data.getElementsByTagName('item')
>>> item = parts[0]
>>> item.childNodes
[<DOM Text node "u'\n     '">, <DOM CDATASection node "u'whatever'">, <DOM Text node "u'\n  '">]
>>> item.childNodes[1].nodeValue = 'changed'
>>> print item.toxml()
<item>
     <![CDATA[changed]]>
  </item>

参见 xml.dom.minidom: Getting CDATA values了解更多详情。

关于python - 找出 CDATA 在 lxml 元素中的位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25171791/

相关文章:

python - Graphviz: <img/> 未显示在 'svg' 输出图像中

python - 在 Elasticsearch DSL 中设置请求特定超时时遇到问题

python - Django 缓存 : reload browser cache when cache is warmed up

python - 使用 Visual Studio C++ 2010 Express 在 Windows x 86(32 位)上为 Python 3.4 安装 lxml

python - 只查找属性完全匹配的 HTML 节点

python - Pyglet 未绘制预定函数

xml - 使用 XML 解析 Swift 库时,Playgrounds 崩溃并显示 "unknown error"

java - 如何在布局中将图像放在textview下面?

java - 从 xml 文档中提取标签

python - lxml - 类型错误 : write() got an unexpected keyword argument 'default_namespace'