将子元素插入到现有 XML 中,两者均使用 Python ElementTree 生成 XML

Inserting Subelement to existing XML both generated using Python ElementTree Generated XML

我正在编写一个函数,使用 ElementTree 和 Python 3.x:

为许多不同的请求生成 xml header
import xml.etree.ElementTree as ET
def xml():
    Message = ET.Element('Message')
    Header = ET.SubElement(Message, 'Header')
    Endpoint = ET.SubElement(Header, 'Endpoint')
    endpoint_id = ET.SubElement(Endpoint, 'ID', value='APP')
    Context = ET.SubElement(Header, 'Context', id='request')
    Itinerary = ET.SubElement(Header, 'Itinerary')
    endpoint_uri = ET.SubElement(Itinerary, 'Endpoint' uri='/blah/blah/common/xml')
    header = ET.tostring(Message)

生成以下输出(经过格式化以便于阅读):

<Message>
 <Header>
  <Endpoint>
   <ID value="APP"/>
  </Endpoint>
  <Context id="request"/>
  <Itinerary>
   <Endpoint uri="/blah/blah/common/xml"/>
  </Itinerary>
 </Header>
</Message>

我正在尝试将以下 XML 插入到“消息”元素上方:

header = xml()

Body = ET.Element('Body')
Account = ET.SubElement(Body, 'Account', operation='query')
id_value = ET.SubElement(Account, 'ID', ns='FOO', value='123456789')
body = ET.tostring(Body)

header.insert(body,'Message')

所以最后会变成这样:

<Message>
 <Header>
  <Endpoint>
   <ID value="APP"/>
  </Endpoint>
  <Context id="request"/>
  <Itinerary>
   <Endpoint uri="/blah/blah/common/xml"/>
  </Itinerary>
 </Header>
 <Body>
  <Account operation="query">
   <ID ns="FOO" value="123456789"/>
  </Account>
 </Body>
</Message>

我遇到的使用 .insert() 执行此操作的所有内容都使用文件中的 XML 示例,这将无法正常工作,因为 XML 文档显然是作为一部分生成的的脚本。脚本失败

AttributeError: 'NoneType' object has no attribute 'insert'

并且在 header 值上尝试 运行 getroot() 失败,因为它需要一个文本文件而不是生成 XML。

尝试改变

header.insert(body,'Message')

Message.insert(1,Body)

看看它是否有效。

想通了:

import xml.etree.ElementTree as ET
import xml.dom.minidom

def xml():
    Message = ET.Element('Message')
    Header = ET.SubElement(Message, 'Header')
    Endpoint = ET.SubElement(Header, 'Endpoint')
    endpoint_id = ET.SubElement(Endpoint, 'ID', value='APP')
    Context = ET.SubElement(Header, 'Context', id='request')
    Itinerary = ET.SubElement(Header, 'Itinerary')
    endpoint_uri = ET.SubElement(Itinerary, 'Endpoint' uri='/blah/blah/common/xml')
    return Message

header = xml()

Body = ET.Element('Body')
Account = ET.SubElement(Body, 'Account', operation='query')
id_value = ET.SubElement(Account, 'ID', ns='FOO', value='123456789')

header.insert(1,Body)
header = ET.tostring(header)
doc = xml.dom.minidom.parseString(header).toprettyxml(indent=" ")
print(doc)

产生:

<Message>
 <Header>
  <Endpoint>
   <ID value="APP"/>
  </Endpoint>
  <Context id="request"/>
  <Itinerary>
   <Endpoint uri="/blah/blah/common/xml"/>
  </Itinerary>
 </Header>
 <Body>
  <Account operation="query">
   <ID ns="FOO" value="123456789"/>
  </Account>
 </Body>
</Message>

H/T Jack Fleeting 插入方法 catch。