'Pass root element as a variable

I have a python function that takes a partial xml string and a root element tag and tries to construct a valid xml. I am having trouble getting this to work.

from lxml import etree
from lxml.builder import E


try:
    root_element = 'TagStatus'
    partial_xml_contents = """<Header>
    <SubmissionType>TVL</SubmissionType>
    <SubmissionDateTime>2019-12-19T09:20:25Z</SubmissionDateTime>
    <SSIOPHubID>9001</SSIOPHubID>
  </Header>
  <Details>
      <RecordType>TB01</RecordType>
      <Status>V</Status>
      <PassInfo>
        <PassType>4</PassType>
        <PassStartDateTime>2019-12-19T08:30:00Z</PassStartDateTime>
        <PassEndDateTime>2019-12-19T18:29:59Z</PassEndDateTime>
      </PassInfo>
      <Class>01</Class>
      <SubDetails>
        <Country>US</Country>
        <State>DE</State>
        <Number>TS00003</Number>
      </SubDetails>
      <AccountDetails>
        <AccountNumber>10061600</AccountNumber>
      </AccountDetails>
    </Details>
"""
    print('root_element: %s' % str(root_element))
    print('partial_contents: %s' % str(partial_xml_contents))
    partial_xml_contents = partial_xml_contents.replace('\n', '')
    retString =  etree.tostring(E(str(root_element), E(str(partial_xml_contents)) ))
    print(retString)
except Exception as e:
    print(str(e))

I'm getting an error: Invalid tag name and the partial contents listed. From my understanding, lxml builder allows for a valid xml to be built using partial chunks.

Edit: Please see the below link. The OP has multiple xml chunks(fully formed). In my case, my xml is partial.

Append xml to xml using python.I have two xml files which i need to merge .so is there anyway i can merge both files



Solution 1:[1]

lxml's E factory can take a tag name as argument, but not a whole XML document. The following much smaller (and well-formed) example also results in a "Invalid tag name" error: E("<tag>x</tag>").

Here is how you can create a well-formed XML document:

from lxml import etree
 
root_element = 'TagStatus'     

partial_xml_contents = """
<Header>
</Header>
<Details>
</Details>"""
 
# Add the root element using an f-string
well_formed_xml_contents = f"<{root_element}>{partial_xml_contents}</{root_element}>"
 
# Verify that there are no errors
root = etree.fromstring(well_formed_xml_contents)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 mzjn