0

Lots of python XML parsing tutorials out there, but not that many on updating XML, and none I can find that match my needs. Sorry for the N00B.

I have a need to add subelements to a particular element based on the value of another subelement.

<CadData>
   <FireIncidentCollection>
      <FireIncident>
         <IncidentNo>12345</IncidentNo>
         <ApparatusCollection>
            <Apparatus>
               <Unit>E29</Unit>
            </Apparatus>
            <Apparatus>
               <Unit>TW29</Unit>
            </Apparatus>
            <Apparatus>
               <Unit>R29</Unit>
            </Apparatus>
         </ApparatusCollection>
      </FireIncident>
   </FireIncidentCollection>
</CadData>

I have values and even other subtrees I need to add based on the "Unit" value of an "Apparatus" element. For example, I may need to add this snippet in that "Apparatus" element when the "Unit"=="TW29":

<DispatchTime>20221115T06:05:04-6.00</DispatchTime>
<ApparatusPersonnelCollection>
  <ApparatusPersonnel>
     <ID>23456</ID>
  </ApparatusPersonnel>
  <ApparatusPersonnel>
    <ID>78901</ID>
</ApparatusPersonnelCollection>

So far I'm resisting the urge to dump everything to a DB and re-writing the whole file each time :). I'm sure there's a way in ElementTree or DOM, but I can't figure it out (not for lack of effort). Any pointers are greatly appreciated. Thanks!
(Oh, and no, I don't control the schema- I just have to adhere to it).

1 Answers1

0

The first step would be to put this information into a dictionary - then it will be much easier to update your data

I'd recommend using xmltodict library with a mixture of this tutorial - which will allow you to convert to a dictionary that you can traverse.

From there, just traverse down the dictionary. The nice thing about the xmltodict library is that it will convert xml with the same tag into a list, so your ApparatusCollection might look something like this once it's converted:

>>> data['CadData']['FireIncidentCollection']['FireIncident']['ApparatusCollection']
{'Apparatus': [{'Unit': 'E29'}, {'Unit': 'TW29'}, {'Unit': 'R29'}]}

Just find the "ApparatusCollect" key, and update the "Apparatus" section. My guess is that it would look close to this:

{'Apparatus': [
  {
   'Unit': 'E29', 
   'DispatchTime':20221115T06:05:04-6.00},
   'ApparatusPersonnelCollection': {
     'ApparatusPersonnel': [23456, 78901]
   } ...

After you've added what you need, just convert the dictionary back into XML.

Hope this helps!

Zach J.
  • 366
  • 6
  • Thanks Zach! I'll investigate that method. I really appreciate the advice! – buckyswider Nov 16 '22 at 13:11
  • No prob @buckyswider ! if it ends up helping you, definitely accept the answer! I'll also check it a bit later today to see if I can refine it – Zach J. Nov 16 '22 at 16:07
  • Oh well, it was a good idea! Unfortunately "xmltodict" and "dicttoxml" are not the exact inverse of one another. The latter adds extra levels for "item" members and groups the individual element tags into a parent node. To relate to my example above: Instead of having multiple sets of entries, it produces . So close and yet so far! – buckyswider Nov 16 '22 at 20:19
  • 1
    OK, I got it! Instead of "dicttoxml" to restore the xml, 'xmltodict' has a built-in "unparse" method. Using that got me back where I started. Thanks Zach! – buckyswider Nov 16 '22 at 22:34