0

I'm using lxml etree to format xml and modify some values. Here's a snippet of the input XML

        <FIELD
            NAME="A"
            SHORT_DESCRIPTION="AAAAA"
            OFFSET="0"
            WIDTH="0"
        >       </FIELD>

        <FIELD
            NAME="B"
            SHORT_DESCRIPTION="BBBBBB"
            OFFSET="1"
            WIDTH="1"
        >       </FIELD>

code:

        from lxml import etree as ET
        tree = ET.parse(path)
        root = tree.getroot()
        #read and modify attributes
        tree.write('output.xml', pretty_print=True) 

But the output is of the form:

 <FIELD NAME="A" SHORT_DESCRIPTION="AAAAA" OFFSET="100" WIDTH="0"> </FIELD>

I tried converting it into a string and then using etree but I get the same results.

I expect it to be in the same format as the XML was originally with the attributes across several lines.

aravi
  • 3
  • 5
  • How are you opening the XML? If you open the file using VScode or another editor as an XML it will format it in the way that you want – Edeki Okoh Sep 19 '19 at 23:33
  • I'm using vim; but the issue is that others would want the XML to be open in human readable form using emacs or vi. – aravi Sep 19 '19 at 23:36
  • Possible duplicate of [Vim indent xml file](https://stackoverflow.com/questions/21408222/vim-indent-xml-file) – Edeki Okoh Sep 19 '19 at 23:38
  • It's more of vim doing its job before I run my script and the script merges all attributes to a single line. – aravi Sep 19 '19 at 23:41

1 Answers1

0

Here is an example of reading, modifying & writing and XML file using lxml:

PS: Your XML input is not valid, you need to wrap it in a parend tag

input.xml

<items>
<FIELD NAME="A" SHORT_DESCRIPTION="AAAAA" OFFSET="0" WIDTH="0"></FIELD>
<FIELD NAME="B" SHORT_DESCRIPTION="BBBBBB" OFFSET="1" WIDTH="1"></FIELD>
</items>

modify_xml.py

from lxml import etree as ET


tree = ET.parse('input.xml')
root = tree.getroot()
# find all fields in the given root
fields = root.iterfind('.//FIELD')
# Example of modifying text and attributes of fields
for field in fields:
    if field.get('OFFSET') == '0':
        field.set('SHORT_DESCRIPTION', 'aaaa')
        field.text = 'TEST 0'
    else:
        field.set('SHORT_DESCRIPTION', 'bbbb')
        field.text = 'TEST 1'

tree.write('output.xml')

output.xml

<items>
<FIELD NAME="A" SHORT_DESCRIPTION="aaaa" OFFSET="0" WIDTH="0">TEST 0</FIELD>
<FIELD NAME="B" SHORT_DESCRIPTION="bbbb" OFFSET="1" WIDTH="1">TEST 1</FIELD>
</items>
Chiheb Nexus
  • 9,104
  • 4
  • 30
  • 43