Nar*_*ael 3 python xml lxml python-3.x
我正在向 xml 文件中添加元素。
文档的根目录如下
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
Run Code Online (Sandbox Code Playgroud)
和要添加的元素看起来像
<Element xsi:type="some type">
<Sub1>Some text</Sub1>
<Sub2>More text</Sub2>
...
</Element>
Run Code Online (Sandbox Code Playgroud)
我试图找到一种方法让 lxml 在我的 Element 的属性前写上“xsi:”。这个 xml 文件被一个程序使用,我无权访问它的源代码。我在其他一些问题中阅读了如何通过声明 xml 根的 nsmap 来实现,然后再次在 child 的属性中,我尝试过但它没有用。到目前为止我有(那是行不通的,输出文件不包含 xsi 前缀):
element = SubElement(_parent=parent,
_tag='some tag',
attrib={'{%s}type' % XSI: 'some type'}
nsmap={'xsi': XSI}) # Where XSI = namespace address
Run Code Online (Sandbox Code Playgroud)
在我解析的 xml 文件中正确声明了命名空间,所以我不知道为什么这不起作用。我得到的输出是如上所示的元素,没有 'xsi:' 前缀,全部在一行中:
<Element type="some type"><Sub1>Some text</Sub1><Sub2>More text</Sub2>...</Element>
Run Code Online (Sandbox Code Playgroud)
如果有人也可以指出为什么在这一行
self.tree.write(self.filename, pretty_print=True, encoding='utf-8')
Run Code Online (Sandbox Code Playgroud)
'pretty_print' 选项不起作用(全部打印在一行中),将不胜感激。
from math import floor
from lxml import etree
from lxml.etree import SubElement
def Element(root, sub1: str):
if not isinstance(sub1, str):
raise TypeError
else:
element = SubElement(root, 'Element')
element_sub1 = SubElement(element, 'Sub1')
element_sub1.text = sub1
# ...
# Omitted additional SubElements
# ...
return element
def Sub(root, sub5_sub: str):
XSI = "http://www.w3.org/2001/XMLSchema-instance"
if not isinstance(sub5_sub, str):
raise TypeError
else:
sub = SubElement(root, 'Sub5_Sub', {'{%s}type' % XSI: 'SomeType'}, nsmap={'xsi': XSI})
# ...
# Omitted additional SubElements
# ...
return sub
class Generator:
def __init__(self) -> None:
self.filename = None
self.csv_filename = None
self.csv_content = []
self.tree = None
self.root = None
self.panel = None
self.panels = None
def mainloop(self) -> None:
"""App's mainloop"""
while True:
# Getting files from user
xml_filename = input('Enter path to xml file : ')
# Parsing files
csv_content = [{'field1': 'ElementSub1', 'field2': 'something'},
{'field1': 'ElementSub1', 'field2': 'something'},
{'field1': 'ElementSub2', 'field2': 'something'}] # Replaces csv file that I use
tree = etree.parse(xml_filename)
root = tree.getroot()
elements = root.find('Elements')
for element in elements:
if element.find('Sub1').text in ['ElementSub1', 'ElementSub2']:
for line in csv_content:
if element.find('Sub5') is not None:
Sub(root=element.find('Sub5'),
sub5_sub=line['field2'])
tree.write(xml_filename, pretty_print=True, encoding='utf-8')
if input('Continue? (Y) Quit (n)').upper().startswith('Y'):
elements.clear()
continue
else:
break
@staticmethod
def get_x(x: int) -> str:
if not isinstance(x, int):
x = int(x)
return str(int(floor(9999 / 9 * x)))
@staticmethod
def get_y(y: int) -> str:
if not isinstance(y, int):
y = int(y)
return str(int(floor(999 / 9 * y)))
def quit(self) -> None:
quit()
if __name__ == "__main__":
app = Generator()
app.mainloop()
app.quit()
Run Code Online (Sandbox Code Playgroud)
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Elements>
<Element>
<Sub1>ElementSub1</Sub1>
<Sub5>
<Sub5_Sub xsi:type="SomeType"/>
<Sub5_Sub xsi:type="SomeType"/><Sub5_Sub xsi:type="SomeType"/><Sub5_Sub xsi:type="SomeType"/></Sub5>
</Element>
<Element>
<Sub1>ElementSub1</Sub1>
<Sub5>
<Sub5_Sub xsi:type="SomeType"/>
<Sub5_Sub xsi:type="SomeType"/>
<Sub5_Sub xsi:type="SomeType"/><Sub5_Sub xsi:type="SomeType"/><Sub5_Sub xsi:type="SomeType"/></Sub5>
</Element>
<Element>
<Sub1>ElementSub1</Sub1>
</Element>
</Elements>
</Root>
Run Code Online (Sandbox Code Playgroud)
出于某种原因,这段代码做了我想要的,但我的真实代码没有。我开始意识到它确实在一些具有 type 属性的子元素上添加了前缀,但不是全部,并且在那些添加前缀的子元素上,它并不总是只是“xsi:”。我找到了一种快速而肮脏的方法来解决这个不太理想的问题(通过 xsi-type 的文件查找和替换 - >被 lxml 的 api 接受到 xsi:type)。尽管pretty_print 参数为真,但仍然无法正常工作的是,它全部打印在一行中。
我最近刚刚遇到这种情况,并且能够成功地创建一个属性 xsi:
qname = etree.QName("http://www.w3.org/2001/XMLSchema-instance", "type")
element = etree.Element('Element', {qname: "some type")
root.append(element)
Run Code Online (Sandbox Code Playgroud)
这输出类似
<Element xsi:type="some type">
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1797 次 |
| 最近记录: |