【问题标题】:Inserting Subelement to existing XML both generated using Python ElementTree Generated XML将子元素插入到使用 Python ElementTree 生成的 XML 生成的现有 XML 中
【发布时间】:2021-11-15 06:23:27
【问题描述】:

我正在编写一个函数来使用 ElementTree 和 Python 3.x 为许多不同的请求生成一个 xml 标头:

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'

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

【问题讨论】:

    标签: python xml xml-parsing elementtree


    【解决方案1】:

    想通了:

    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。

    【讨论】:

    • 现在我明白你在做什么了!很高兴看到它有效。
    【解决方案2】:

    尝试改变

    header.insert(body,'Message')
    

    Message.insert(1,Body)
    

    看看它是否有效。

    【讨论】:

    • 同样的问题AttributeError: 'NoneType' object has no attribute 'insert'
    • .insert() 方法对 Message 不起作用,因为它在函数内部,这就是为什么我仍然收到该错误。
    • @drfunkenstein 您究竟是如何获得输出的(您问题中的第一个 xml)?
    猜你喜欢
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多