vector8188
vector8188

Reputation: 1393

lxml etree.fromstring not creating correct XML doc

Hello everyone I have a trivial question regarding lxml so below is the XML I want to properly format into regular xml object which will be eventually stored in a file. content of 'ToXMLData.xml'

<?xml version="1.0"?><imdata><fvTenant name='t2' status='created,modified'><dbgacEpgToEpg name='dbgacepg2epg2' status='created,modified'></dbgacEpgToEpg><fvBD name='b6' status='created,modified'><fvSubnet ip='56.0.5.1/24' status='created,modified'></fvSubnet><fvRsCtx status='created,modified' tnFvCtxName='ctx2'></fvRsCtx></fvBD><dbgacAnyToEp name='dbgacany2ep2' status='created,modified'></dbgacAnyToEp><dbgacEpgToIp name='dbgacepg2ip2' status='created,modified'></dbgacEpgToIp></fvTenant><fvTenant name='t1' status='created,modified'><dbgacEpgToEpg name='dbgacepg2epg2' status='created,modified'></dbgacEpgToEpg><fvBD name='b6' status='created,modified'><fvSubnet ip='56.0.5.1/24' status='created,modified'></fvSubnet><fvRsCtx status='created,modified' tnFvCtxName='ctx2'></fvRsCtx></fvBD><dbgacAnyToEp name='dbgacany2ep2' status='created,modified'></dbgacAnyToEp><dbgacEpgToIp name='dbgacepg2ip2' status='created,modified'></dbgacEpgToIp></fvTenant>`</imdata>


xmlDataFileNameNew = 'ToXMLData.xml'
xmlDataFileHandler = open(xmlDataFileNameNew,'r+')
xmlstring = xmlDataFileHandler.read()
print xmlstring
root = etree.fromstring(xmlstring)
print root

and the output for the code above is

xmlstring >> <?xml version="1.0"?><imdata><fvTenant name='t2' status='created,modified'><dbgacEpgToEpg name='dbgacepg2epg2' status='created,modified'></dbgacEpgToEpg><fvBD name='b6' status='created,modified'><fvSubnet ip='56.0.5.1/24' status='created,modified'></fvSubnet><fvRsCtx status='created,modified' tnFvCtxName='ctx2'></fvRsCtx></fvBD><dbgacAnyToEp name='dbgacany2ep2' status='created,modified'></dbgacAnyToEp><dbgacEpgToIp name='dbgacepg2ip2' status='created,modified'></dbgacEpgToIp></fvTenant><fvTenant name='t1' status='created,modified'><dbgacEpgToEpg name='dbgacepg2epg2' status='created,modified'></dbgacEpgToEpg><fvBD name='b6' status='created,modified'><fvSubnet ip='56.0.5.1/24' status='created,modified'></fvSubnet><fvRsCtx status='created,modified' tnFvCtxName='ctx2'></fvRsCtx></fvBD><dbgacAnyToEp name='dbgacany2ep2' status='created,modified'></dbgacAnyToEp><dbgacEpgToIp name='dbgacepg2ip2' status='created,modified'></dbgacEpgToIp></fvTenant>`</imdata>

root>> <Element imdata at 292aaa0>

I am sorry, I should have been clear first time. what i want to do is to convert the ugly xml given above to the standard machine readable one. An example ----->

<?xml version="1.0" encoding="UTF-8"?>
<imdata>
   <fvTenant name="t2" status="created,modified">
      <dbgacEpgToEpg name="dbgacepg2epg2" status="created,modified" />
      <fvBD name="b6" status="created,modified">
         <fvSubnet ip="56.0.5.1/24" status="created,modified" />
         <fvRsCtx status="created,modified" tnFvCtxName="ctx2" />
      </fvBD>
      <dbgacAnyToEp name="dbgacany2ep2" status="created,modified" />
      <dbgacEpgToIp name="dbgacepg2ip2" status="created,modified" />
   </fvTenant>
   <fvTenant name="t1" status="created,modified">
      <dbgacEpgToEpg name="dbgacepg2epg2" status="created,modified" />
      <fvBD name="b6" status="created,modified">
         <fvSubnet ip="56.0.5.1/24" status="created,modified" />
         <fvRsCtx status="created,modified" tnFvCtxName="ctx2" />
      </fvBD>
      <dbgacAnyToEp name="dbgacany2ep2" status="created,modified" />
      <dbgacEpgToIp name="dbgacepg2ip2" status="created,modified" />
   </fvTenant>
</imdata>

Upvotes: 0

Views: 518

Answers (2)

unutbu
unutbu

Reputation: 880767

Near the end of your XML there appears to be a stray backtick:

</dbgacEpgToIp></fvTenant>`</imdata>
                          ^

It does not appear in your desired result:

      <dbgacEpgToIp name="dbgacepg2ip2" status="created,modified" />
   </fvTenant>
</imdata>

If the backtick is removed, then

import lxml.etree as ET
xmlDataFileNameNew = 'ToXMLData.xml'
xmlDataFileHandler = open(xmlDataFileNameNew,'r+')
xmlstring = xmlDataFileHandler.read()
root = ET.fromstring(xmlstring)
print(ET.tostring(root, pretty_print=True))

yields

<imdata>
  <fvTenant name="t2" status="created,modified">
    <dbgacEpgToEpg name="dbgacepg2epg2" status="created,modified"/>
    <fvBD name="b6" status="created,modified">
      <fvSubnet ip="56.0.5.1/24" status="created,modified"/>
      <fvRsCtx status="created,modified" tnFvCtxName="ctx2"/>
    </fvBD>
    <dbgacAnyToEp name="dbgacany2ep2" status="created,modified"/>
    <dbgacEpgToIp name="dbgacepg2ip2" status="created,modified"/>
  </fvTenant>
  <fvTenant name="t1" status="created,modified">
    <dbgacEpgToEpg name="dbgacepg2epg2" status="created,modified"/>
    <fvBD name="b6" status="created,modified">
      <fvSubnet ip="56.0.5.1/24" status="created,modified"/>
      <fvRsCtx status="created,modified" tnFvCtxName="ctx2"/>
    </fvBD>
    <dbgacAnyToEp name="dbgacany2ep2" status="created,modified"/>
    <dbgacEpgToIp name="dbgacepg2ip2" status="created,modified"/>
  </fvTenant>
</imdata>

Upvotes: 1

mgilson
mgilson

Reputation: 310227

Printing root gives you the python __str__ of the object (in this case the object is an Element instance). If you actually want to represent your xml tree as a string (i.e. return basically the xml string you put in with some formatting differences), you can use the etree.tostring function.

i.e:

print etree.tostring(root)

Upvotes: 1

Related Questions