title: Parsing an XML file to convert to a CSV
body: <p>I am having trouble parsing elements properly from an xml file (see xml snippet below) and converting them into a csv.</p>
  <p>The csv file has columns for <code>eventType</code>, <code>probableCause</code>, <code>alarmName</code>, <code>shortName (ACAT, AC etc)</code>, and <code>longName (ACTangent, ACODE, etc)</code></p>
  <p>similar idea to this:</p>
  <p><a href="https://i.stack.imgur.com/YZtgB.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/YZtgB.png" alt="enter image description here" /></a></p>
  <p>At the moment, I can only get it to start parsing information from the alarm, but I would like it to start from the very beginning. How can I extract the family longName in one column and the family shortName in another column for every single log and alarm?</p>
  <p>Please let me know if any clarification is needed.</p>
  <p>XML sample:</p>
  <pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
  
  &lt;faults version=&quot;1&quot; xmlns=&quot;urn:nortel:namespaces:mcp:faults&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:schemaLocation=&quot;urn:nortel:namespaces:mcp:faults NortelFaultSchema.xsd &quot;&gt;
      &lt;family longName=&quot;1OffMsgr&quot; shortName=&quot;OOM&quot;/&gt;
      &lt;family longName=&quot;ACTAGENT&quot; shortName=&quot;ACAT&quot;&gt;
          &lt;logs&gt;
             &lt;log&gt;
                  &lt;eventType&gt;RES&lt;/eventType&gt;
                  &lt;number&gt;1&lt;/number&gt;
                  &lt;severity&gt;INFO&lt;/severity&gt;
                  &lt;descTemplate&gt;
                       &lt;msg&gt;Accounting is enabled upon this NE.&lt;/msg&gt;
                 &lt;/descTemplate&gt;
                 &lt;note&gt;This log is generated when setting a Session Manager's AM from &amp;lt;none&amp;gt; to a valid AM.&lt;/note&gt;
                 &lt;om&gt;On all instances of this Session Manager, the &amp;lt;NE_Inst&amp;gt;:&amp;lt;AM&amp;gt;:STD:acct OM row in the  StdRecordStream group will appear and start counting the recording units sent to the configured AM.
                     On the configured AM, the &amp;lt;NE_inst&amp;gt;:acct OM rows in RECSTRMCOLL group will appear and start counting the recording units received from this Session Manager's instances.
                 &lt;/om&gt;
              &lt;/log&gt;
             &lt;log&gt;
                  &lt;eventType&gt;RES&lt;/eventType&gt;
                  &lt;number&gt;2&lt;/number&gt;
                  &lt;severity&gt;ALERT&lt;/severity&gt;
                  &lt;descTemplate&gt;
                       &lt;msg&gt;Accounting is disabled upon this NE.&lt;/msg&gt;
                 &lt;/descTemplate&gt;
                 &lt;note&gt;This log is generated when setting a Session Manager's AM from a valid AM to &amp;lt;none&amp;gt;.&lt;/note&gt;
                 &lt;action&gt;If you do not intend for the Session Manager to produce accounting records, then no action is required.  If you do intend for the Session Manager to produce accounting records, then you should set the Session Manager's AM to a valid AM.&lt;/action&gt;
                 &lt;om&gt;On all instances of this Session Manager, the &amp;lt;NE_Inst&amp;gt;:&amp;lt;AM&amp;gt;:STD:acct OM row in the StdRecordStream group that matched the previous datafilled AM will disappear.
                     On the previously configured AM, the  &amp;lt;NE_inst&amp;gt;:acct OM rows in RECSTRMCOLL group will disappear.
                 &lt;/om&gt;
              &lt;/log&gt;
          &lt;/logs&gt;
      &lt;/family&gt;
      &lt;family longName=&quot;ACODE&quot; shortName=&quot;AC&quot;&gt;
          &lt;alarms&gt;
              &lt;alarm&gt;
                  &lt;eventType&gt;ADMIN&lt;/eventType&gt;
                  &lt;number&gt;1&lt;/number&gt;
                  &lt;probableCause&gt;INFORMATION_MODIFICATION_DETECTED&lt;/probableCause&gt;
                  &lt;descTemplate&gt;
                      &lt;msg&gt;Configured data for audiocode server updated: $1&lt;/msg&gt;
                       &lt;param&gt;
                           &lt;num&gt;1&lt;/num&gt;
                           &lt;description&gt;AudioCode configuration data got updated&lt;/description&gt;
                           &lt;exampleValue&gt;acgwy1&lt;/exampleValue&gt;
                       &lt;/param&gt;
                 &lt;/descTemplate&gt;
                 &lt;manualClearable&gt;&lt;/manualClearable&gt;
                 &lt;correctiveAction&gt;None. Acknowledge/Clear alarm and deploy the audiocode server if appropriate.&lt;/correctiveAction&gt;
                 &lt;alarmName&gt;Audiocode Server Updated&lt;/alarmName&gt;
                 &lt;severities&gt;
                       &lt;severity&gt;MINOR&lt;/severity&gt;
                 &lt;/severities&gt;               
              &lt;/alarm&gt;
              &lt;alarm&gt;
                  &lt;eventType&gt;ADMIN&lt;/eventType&gt;
                  &lt;number&gt;2&lt;/number&gt;
                  &lt;probableCause&gt;CONFIG_OR_CUSTOMIZATION_ERROR&lt;/probableCause&gt;
                  &lt;descTemplate&gt;
                      &lt;msg&gt;Deployment for audiocode server failed: $1. Reason: $2.&lt;/msg&gt;
                       &lt;param&gt;
                           &lt;num&gt;1&lt;/num&gt;
                           &lt;description&gt;AudioCode Name&lt;/description&gt;
                           &lt;exampleValue&gt;audcod&lt;/exampleValue&gt;
                       &lt;/param&gt;
                       &lt;param&gt;
                           &lt;num&gt;2&lt;/num&gt;
                           &lt;description&gt;AudioCode Deployment failed reason&lt;/description&gt;
                           &lt;exampleValue&gt;Failed to parse audiocode configuration data&lt;/exampleValue&gt;
                       &lt;/param&gt;
                 &lt;/descTemplate&gt;
                 &lt;manualClearable&gt;&lt;/manualClearable&gt;
                 &lt;correctiveAction&gt;Check the configuration of audiocode server. Acknowledge/Clear alarm and deploy the audiocode server if appropriate.&lt;/correctiveAction&gt;
                 &lt;alarmName&gt;Audiocode Server Deploy Failed&lt;/alarmName&gt;
                 &lt;severities&gt;
                       &lt;severity&gt;MINOR&lt;/severity&gt; 
                 &lt;/severities&gt;               
              &lt;/alarm&gt;
          &lt;/alarms&gt;
      &lt;/family&gt;
  &lt;/faults&gt;
  </code></pre>
  <p>My code</p>
  <pre><code>from xml.etree import ElementTree
  import csv
  
  
  tree = ElementTree.parse('Fault.xml')
  
  sitescope_data = open('Out.csv', 'w', newline='', encoding='utf-8')
  csvwriter = csv.writer(sitescope_data)
  
  #Create all needed columns here in order and writes them to excel file
  col_names = ['eventType', 'probableCause', 'severity', 'alarmName', 'shortName', 'longName']
  csvwriter.writerow(col_names)
  
  def recurse(root):
      for child in root:
          recurse(child)
          print(child.tag)
  
      for  event in root.findall('{urn:nortel:namespaces:mcp:faults}alarm'):
          event_data = []
          event_id = event.find('{urn:nortel:namespaces:mcp:faults}eventType')
          if event_id != None:
              event_id = event_id.text
          event_data.append(event_id)
  
          probableCause = event.find('{urn:nortel:namespaces:mcp:faults}probableCause')
          if probableCause != None:
              probableCause = probableCause.text
          event_data.append(probableCause)
  
          severities = event.find('{urn:nortel:namespaces:mcp:faults}severities')
          if severities:
              severity_data = ','.join(
                  [sv.text for sv in severities.findall('{urn:nortel:namespaces:mcp:faults}severity')])
              event_data.append(severity_data)
          else:
              event_data.append(&quot;&quot;)
  
          alarmName = event.find('{urn:nortel:namespaces:mcp:faults}alarmName')
          if alarmName != None:
              alarmName = alarmName.text
          event_data.append(alarmName)
  
          csvwriter.writerow(event_data)
  
  root = tree.getroot()
  recurse(root)
  sitescope_data.close()
  
  </code></pre>
  <p><strong>UPDATE</strong></p>
  <p>I am having trouble parsing data in this manner for another XML file:
  <a href="https://i.stack.imgur.com/lp0Ny.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/lp0Ny.png" alt="enter image description here" /></a></p>
  <p>For the first column, I would like to get the general name tag (recordingSystem, Ports, etc) and concatenate it with the subNames in the row tags (closedFileCount, processedFileCount, etc)</p>
  <p>The problem I noticed is that the tag where the subName is located keeps changing, it could be a &quot;usage&quot;, &quot;lwGuage&quot;, &quot;hwGauge&quot; and so on. I also need to collect those and put it in the column beside it.</p>
  <p>Please see the sample XML below:</p>
  <pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
  
  &lt;omGroups xmlns=&quot;urn:nortel:namespaces:mcp:oms&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:schemaLocation=&quot;urn:nortel:namespaces:mcp:oms OMSchema.xsd&quot; &gt;
  
          &lt;group&gt;
                  &lt;name&gt;RecordingSystem&lt;/name&gt;
                  &lt;row&gt;
                          &lt;package&gt;com.nortelnetworks.mcp.ne.base.recsystem.fw.system&lt;/package&gt;
                          &lt;class&gt;RecSysFileOMRow&lt;/class&gt;
                          &lt;usage name=&quot;closedFileCount&quot; hasThresholds=&quot;true&quot;&gt;
                                  &lt;measures&gt;
                                          closed file count
                                  &lt;/measures&gt;
                                  &lt;description&gt;
                                          This register counts the number
                                          of closed files in the spool directory of a
                                          particular stream and a particular system.
                                          Files in the spool directory store the raw
                                          OAM records where they are sent to the
                                          Element Manager for formatting.
                                  &lt;/description&gt;
                                  &lt;notes&gt;
                                          Minor and major alarms
                                          when the value of closedFileCount
                                          exceeds certain thresholds. Configure
                                          the threshold values for minor and major
                                          alarms for this OM through engineering
                                          parameters for minorBackLogCount and
                                          majorBackLogCount, respectively. These
                                          engineering parameters are grouped under
                                          the parameter group of Log, OM, and
                                          Accounting for the logs’ corresponding
                                          system.
                                  &lt;/notes&gt;
                          &lt;/usage&gt;
                          &lt;usage name=&quot;processedFileCount&quot; hasThresholds=&quot;true&quot;&gt;
                                  &lt;measures&gt;
                                          Processed file count
                                  &lt;/measures&gt;
                                  &lt;description&gt;
                                          The register counts the number
                                          of processed files in the spool directory of
                                          a particular stream and a particular system.
                                          Files in the spool directory store the raw
                                          OAM records and then send the records to
                                          the Element Manager for formatting.
                                  &lt;/description&gt;
                          &lt;/usage&gt;
                  &lt;/row&gt;
                  &lt;documentation&gt;
                          &lt;description&gt;
                                  Rows of this OM group provide a count of the number of files contained
                                  within the directory (which is the OM row key value).
                          &lt;/description&gt;
                          &lt;rowKey&gt;
                                  The full name of the directory containing the files counted by this row.
                          &lt;/rowKey&gt;
                  &lt;/documentation&gt;
                  &lt;generatedOn&gt;
                          &lt;all/&gt;
                  &lt;/generatedOn&gt;
          &lt;/group&gt;
          &lt;group traffic=&quot;true&quot;&gt;
                  &lt;name&gt;Ports&lt;/name&gt;
                  &lt;row&gt;
                          &lt;package&gt;com.nortelnetworks.ims.cap.mediaportal.host&lt;/package&gt;
                          &lt;class&gt;PortsOMRow&lt;/class&gt;
                          &lt;usage name=&quot;rtpMpPortUsage&quot;&gt;
                                  &lt;measures&gt;
                                          BCP port usage
                                  &lt;/measures&gt;
                                  &lt;description&gt;
                                          Meter showing number of ports in use.
                                  &lt;/description&gt;
                          &lt;/usage&gt;
                          &lt;lwGauge name=&quot;connMapEntriesLWM&quot;&gt;
                                  &lt;measures&gt;
                                          Lowest simultaneous port usage
                                  &lt;/measures&gt;
                                  &lt;description&gt;
                                          Lowest number of
                                          simultaneous ports detected to be in
                                          use during the collection interval
                                  &lt;/description&gt;
                          &lt;/lwGauge&gt;
                          &lt;hwGauge name=&quot;connMapEntriesHWM&quot;&gt;
                                  &lt;measures&gt;
                                          Highest simultaneous port usage
                                  &lt;/measures&gt;
                                  &lt;description&gt;
                                          Highest number of
                                          simultaneous ports detected to be in
                                          use during the collection interval.
                                  &lt;/description&gt;
                          &lt;/hwGauge&gt;
                          &lt;waterMark name=&quot;connMapEntries&quot;&gt;
                                  &lt;measures&gt;
                                          Connections map entries
                                  &lt;/measures&gt;
                                  &lt;description&gt;
                                          Meter showing the number of connections in the host
                                          CPU connection map.
                                  &lt;/description&gt;
                                  &lt;bwg lwref=&quot;connMapEntriesLWM&quot; hwref=&quot;connMapEntriesHWM&quot;/&gt;
                          &lt;/waterMark&gt;
                          &lt;counter name=&quot;portUsageSampleCnt&quot;&gt;
                                  &lt;measures&gt;
                                      Usage sample count
                                  &lt;/measures&gt;
                                  &lt;description&gt;
                                      The number of 100-second samples taken during the
                                      collection interval contributing to the average report.
                                  &lt;/description&gt;
                          &lt;/counter&gt;
                          &lt;counter name=&quot;sampledRtpMpPortUsage&quot;&gt;
                                  &lt;measures&gt;
                                      In-use ports usage
                                  &lt;/measures&gt;
                                  &lt;description&gt;
                                      Provides the sum of the in-use ports every 100 seconds.
                                  &lt;/description&gt;
                          &lt;/counter&gt;
                          &lt;precollector&gt;
                                  &lt;package&gt;com.nortelnetworks.ims.cap.mediaportal.host&lt;/package&gt;
                                  &lt;class&gt;PortsOMCenturyPrecollector&lt;/class&gt;
                                  &lt;collector&gt;centurySecond&lt;/collector&gt;
                          &lt;/precollector&gt;
                  &lt;/row&gt;
                  &lt;documentation&gt;
                          &lt;description&gt;
                          &lt;/description&gt;
                          &lt;rowKey&gt;
                          &lt;/rowKey&gt;
                  &lt;/documentation&gt;
                  &lt;generatedOn&gt;
                          &lt;list&gt;
                              &lt;ne&gt;sessmgr&lt;/ne&gt;
                              &lt;ne&gt;rtpportal&lt;/ne&gt;
                          &lt;/list&gt;
                  &lt;/generatedOn&gt;
          &lt;/group&gt;
         
  &lt;/omGroups&gt;
  
  </code></pre>