使用Python创建具有特定顺序或属性的XML文件

2024-06-18 14:38:15 发布

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

我正在尝试使用lxml创建一个xml文件,我很清楚xml中属性的顺序并不重要,但我仍然在寻找一种方法来防止属性以特定的顺序出现

我也尝试了minidom,但也没有锻炼

在lxml中,我有以下代码:

from lxml import etree as ET
from collections import OrderedDict
root = ET.Element("Root", OrderedDict([("id","0"),("start","0"),("end","200")]))
ET.tostring(root)

由于我在这里使用了OrderedDict,因此本部分按照我想要的顺序提供了以下属性输出:

<Root id="0" start="0" end="200"/>

然后,我使用相同的方法创建了一个子对象:

child1 = ET.Element("sentence", OrderedDict([("id","0"),("start","0"),("end","255")]))
root.append(child1)
xml_str = ET.tostring(root, pretty_print=True)
print(xml_str)

打印xml_str会产生预期的输出:

<Root id="0" start="0" end="200">\n  <sentence id="0" start="0" end="255"/>\n</Root>

但在将其写入xml文件时:

with open('op.xml', 'wb') as f:
  f.write(xml_str)

写入op.xml文件时,输出不同:

<?xml version="1.0"?>

<Root end="200" start="0" id="0">
       <sentence end="255" start="0" id="0"/>
</Root>

可以清楚地看到属性顺序已经改变,是否有任何方法可以获得预期的输出,即维护属性顺序

我也尝试过使用minidom,但在提到以下内容后,它仍然不起作用: Preserve order of attributes when modifying with minidom


Tags: 文件方法id属性顺序rootxmlstart
2条回答

这是一个库,它擅长提取数据,不擅长修改XML文件,但基本上可以满足您的需要

from simplified_scrapy import SimplifiedDoc, utils, req
doc = SimplifiedDoc("<Root></Root>")
doc.Root.setAttrs({"id":"0","start":"0","end":"200"})
doc.Root.setContent("<sentence />")
doc.sentence.setAttrs({"id":"0","start":"0","end":"200"})
utils.saveFile("op.xml",doc.html)

结果:

<Root id="0" start="0" end="200"><sentence id="0" start="0" end="200" /></Root>

使用lxml.etree可以使其工作:

import lxml.etree
from collections import OrderedDict

root = lxml.etree.Element("Root", OrderedDict([("id","0"),("start","0"),("end","200")]))
isVal = lxml.etree.SubElement(root, 'sentence', OrderedDict([("id","0"),("start","0"),("end","255")]))

with open("xyz2.xml", 'wb') as f:
    f.write(lxml.etree.tostring(root, xml_declaration=True, encoding="utf-8"))

print(open("xyz2.xml", 'r').read())

输出:

<?xml version='1.0' encoding='utf-8'?>
<Root id="0" start="0" end="200"><sentence id="0" start="0" end="255"/></Root>

相关问题 更多 >