我刚刚发现lxml.objectify这对于读取/写入简单的 XML 文件来说似乎很好并且很容易。
首先,使用 是一个好主意吗lxml.objectify?例如,它是否成熟且仍在开发中并且可能在未来可用?
其次,如何防止objectify添加像xmlns:py="http://codespeak.net/lxml/objectify/pytype" py:pytype="str"下面的输出中那样的标记?
输入:config.xml
<?xml version="1.0" encoding="utf-8"?>
<Test>
<MyElement1>sdfsdfdsfd</MyElement1>
</Test>
Run Code Online (Sandbox Code Playgroud)
代码
from lxml import etree, objectify
with open('config.xml') as f:
xml = f.read()
root = objectify.fromstring(xml)
root.Information = 'maybe'
print etree.tostring(root, pretty_print=True)
Run Code Online (Sandbox Code Playgroud)
输出
<Test>
<MyElement1>sdfsdfdsfd</MyElement1>
<Information xmlns:py="http://codespeak.net/lxml/objectify/pytype" py:pytype="str">maybe</Information>
</Test>
Run Code Online (Sandbox Code Playgroud) 我正在将大量数据从数据库写入 XML 文件。我正在使用 Python 及其 lxml 库来创建该文件。我注意到它在内存中生成整个 XML 文件,然后将其输出到最后的文件中,是否有一种方法可以为每 X 个数据库对象转储 xml 文件?
import lxml.etree as etree
import os
root = etree.Element('root')
db_obj1 = etree.SubElement(root, 'item')
db_obj2 = etree.SubElement(root, 'item')
db_obj3 = etree.SubElement(root, 'item')
et = etree.ElementTree(root)
et.write(sys.stdout)
Run Code Online (Sandbox Code Playgroud)
我尝试过使用 ElemenTree().write(),但在http://lxml.de/api/lxml.etree._ElementTree-class的文档中找不到有关如何完成此操作的任何设置或最佳实践.html。
寻求减少总内存占用。
我正在使用 lxml iterwalk 迭代 HTML 树,我想用新行字符替换<br>里面的所有标签。<pre></pre>这就是我到目前为止所拥有的:
root = lxml.html.fromstring(text)
for action, el in etree.iterwalk(root):
if el.tag == 'pre':
for br in el.xpath('br'):
# replace this <br> tag with "\n"
Run Code Online (Sandbox Code Playgroud)
如果可能的话,替换实际上应该在这个循环内完成,因为无论如何我们都需要循环,并且在其中包含此步骤可能是最有效的方法。
SO 上有一个类似的问题/答案,但它无助于解决问题: How can one Replace an element with text in lxml?
如何将etree 中某个元素之前的所有文本与该元素之后的文本分开?
from lxml import etree
tree = etree.fromstring('''
<a>
find
<b>
the
</b>
text
<dd></dd>
<c>
before
</c>
<dd></dd>
and after
</a>
''')
Run Code Online (Sandbox Code Playgroud)
我想要什么?在此示例中,<dd>标签是分隔符,并且对于所有标签
for el in tree.findall('.//dd'):
Run Code Online (Sandbox Code Playgroud)
我想要它们之前和之后的所有文本:
[
{
el : <Element dd at 0xsomedistinctadress>,
before : 'find the text',
after : 'before and after'
},
{
el : <Element dd at 0xsomeotherdistinctadress>,
before : 'find the text before',
after : 'and after'
}
]
Run Code Online (Sandbox Code Playgroud)
我的想法是在树中使用某种占位符,用它替换标签<dd>,然后在该占位符处剪切字符串,但我需要与实际元素的对应关系。
我有一个非常大的 XML 日志文件,它会以固定大小 (~200MB) 自动分割。可以有很多部分(通常少于 10 个)。当它拆分时,它不会在记录末尾甚至当前行末尾整齐地进行拆分。一旦达到目标尺寸,它就会分裂。
time基本上我需要解析这些文件中的“记录”元素,然后从每个文件中取出子文件
由于这些日志文件在随机位置分割并且不一定有根目录,因此我将 Python3 和 lxmletree.iterparse与html=True. 这是处理由于分割文件而导致缺少根节点的情况。但是,我不确定如何处理最终在一个文件的末尾和另一个文件的开头之间分割的记录。
以下是分割文件的一个小示例。
文件:测试.001.txt
<records>
<record>
<data>5</data>
<time>1</time>
</record>
<record>
<data>5</data>
<time>2</time>
</record>
<record>
<data>5</data>
<ti
Run Code Online (Sandbox Code Playgroud)
文件:测试.002.txt
me>3</time>
</record>
<record>
<data>6</data>
<time>4</time>
</record>
<record>
<data>6</data>
<time>5</time>
</record>
</records>
Run Code Online (Sandbox Code Playgroud)
这是我尝试过的方法,但我知道它不能正常工作:
from lxml import etree
xmlFiles = []
xmlFiles.append('test.001.txt')
xmlFiles.append('test.002.txt')
timeStamps = []
for xmlF in xmlFiles:
for event, elem in etree.iterparse(xmlF, events=("end",), tag='record',html=True):
tElem = elem.find('time')
if tElem is not None:
timeStamps.append(int(tElem.text))
Run Code Online (Sandbox Code Playgroud)
输出:
In[20] : …Run Code Online (Sandbox Code Playgroud) 我正在开发一个使用 lxml 来废弃页面的 python 项目,并且我面临着检索 span 类属性名称的挑战。html 片段如下:
<tr class="nogrid">
<td class="date">12th January 2016</td>
<td class="time">11:22pm</td>
<td class="category">Clothing</td>
<td class="product">
<span class="brand">carlos santos</span>
</td>
<td class="size">10</td>
<td class="name">polo</td>
</tr>
....
Run Code Online (Sandbox Code Playgroud)
如何检索下面的跨度类属性的值:
<span class="brand">carlos santos</span>
Run Code Online (Sandbox Code Playgroud) 在符号“\n”之后,pretty_print 被忽略。例如:
import lxml.etree as etree
strs = ["<root>\n<e1/><e2/></root>",
"<root><e1/><e2/></root>"]
for str in strs:
xml = etree.fromstring(str)
print etree.tostring(xml, pretty_print=True)
Run Code Online (Sandbox Code Playgroud)
输出是:
<root>
<e1/><e2/></root>
<root>
<e1/>
<e2/>
</root>
Run Code Online (Sandbox Code Playgroud)
两个字符串都是有效的 xml。第一个字符串有符号“\n”,该符号后的 Pretty_print 将被忽略。
是它和 lxml 错误还是我需要特殊操作才能进行漂亮的格式化?
我习惯在Elements上操作,而不是ElementTrees。
到目前为止,我可以使用以下方法从 an 转换ElementTree为 an Element:
tree = et.parse(xml_location)
et.fromstring(et.tostring(tree))
Run Code Online (Sandbox Code Playgroud)
但这看起来很昂贵 - 除了上述方法之外,是否还有从 an 转换ElementTree为 an的传统方法?Element
我有一个 lxmlElement对象:
>>> from lxml import etree
>>> xml_str = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<state type=\"before_battle\">\n</state>"
>>> etree.fromstring(xml_str.encode('utf-8'))
<Element state at 0x7fd04b957e48>
Run Code Online (Sandbox Code Playgroud)
如何获取字符串转储Element?
我正在尝试通过 BeautifulSoup 用 lxml 解析一个很长的 html 文件。我知道 html 文件的字符编码是,UTF-8 with BOM但是每当我尝试运行时,contents = f.read()我都会收到以下错误:'charmap' codec can't decode byte 0x8d in position 33222: character maps to <undefined>
这是我的代码的第一个(也是有问题的)位:
from bs4 import BeautifulSoup
with open("doc.html", "r") as f:
contents = f.read()
soup = BeautifulSoup(contents, 'lxml')
print(soup.h2)
print(soup.head)
print(soup.li)
Run Code Online (Sandbox Code Playgroud)
这是错误显示:
UnicodeDecodeError Traceback (most recent call last)
<ipython-input-1-4805460879e0> in <module>
3 with open("doc.html", "r") as f:
4
----> 5 contents = f.read()
6
7 soup = BeautifulSoup(contents, 'lxml')
~\Anaconda3\lib\encodings\cp1252.py in …Run Code Online (Sandbox Code Playgroud) lxml ×10
python ×10
html ×3
xml ×3
elementtree ×2
xml-parsing ×2
element ×1
encoding ×1
html-parsing ×1
methods ×1
pretty-print ×1
replace ×1