content: '******************************************************
  'Get all XML subelements by name
  '
  'return list of 0 or more elements
  '******************************************************
  Function AkaMA_GetXMLElementsByName(xml As Object, name As String) As Object
      list = CreateObject("roArray", 100, true)
      if AkaMA_islist(xml.GetBody()) = false return list
  
      for each e in xml.GetBody()
          if e.GetName() = name then
              list.Push(e)
          endif
      next
  
      return list
  End Function
  
  
  '******************************************************
  'Get all XML subelement's string bodies by name
  '
  'return list of 0 or more strings
  '******************************************************
  Function AkaMA_GetXMLElementBodiesByName(xml As Object, name As String) As Object
      list = CreateObject("roArray", 100, true)
      if AkaMA_islist(xml.GetBody()) = false return list
  
      for each e in xml.GetBody()
          if e.GetName() = name then
              b = e.GetBody()
              if type(b) = "roString" or type(b) = "String" list.Push(b)
          endif
      next
  
      return list
  End Function
  
  
  '******************************************************
  'Get first XML subelement by name
  '
  'return invalid if not found, else the element
  '******************************************************
  Function AkaMA_GetFirstXMLElementByName(xml As Object, name As String) As dynamic
      if AkaMA_islist(xml.GetBody()) = false return invalid
  
      for each e in xml.GetBody()
          if e.GetName() = name return e
      next
  
      return invalid
  End Function
  
  
  '******************************************************
  'Get first XML subelement's string body by name
  '
  'return invalid if not found, else the subelement's body string
  '******************************************************
  Function AkaMA_GetFirstXMLElementBodyStringByName(xml As Object, name As String) As dynamic
      e = AkaMA_GetFirstXMLElementByName(xml, name)
      if e = invalid return invalid
      if type(e.GetBody()) <> "roString" and type(e.GetBody()) <> "String" return invalid
      return e.GetBody()
  End Function
  
  
  '******************************************************
  'Get the xml element as an integer
  '
  'return invalid if body not a string, else the integer as converted by strtoi
  '******************************************************
  Function AkaMA_GetXMLBodyAsInteger(xml As Object) As dynamic
      if type(xml.GetBody()) <> "roString" and type(xml.GetBody()) <> "String" return invalid
      return strtoi(xml.GetBody())
  End Function
  
  
  '******************************************************
  'Parse a string into a roXMLElement
  '
  'return invalid on error, else the xml object
  '******************************************************
  Function AkaMA_ParseXML(str As String) As dynamic
      if str = invalid return invalid
      xml=CreateObject("roXMLElement")
      if not xml.Parse(str) return invalid
      return xml
  End Function
  
  '******************************************************
  'Get XML sub elements whose bodies are strings into an associative array.
  'subelements that are themselves parents are skipped
  'namespace :'s are replaced with _'s
  '
  'So an XML element like...
  '
  '<blah>
  '    <This>abcdefg</This>
  '    <Sucks>xyz</Sucks>
  '    <sub>
  '        <sub2>
  '        ....
  '        </sub2>
  '    </sub>
  '    <ns:doh>homer</ns:doh>
  '</blah>
  '
  'returns an AA with:
  '
  'aa.This = "abcdefg"
  'aa.Sucks = "xyz"
  'aa.ns_doh = "homer"
  '
  'return an empty AA if nothing found
  '******************************************************
  Sub AkaMA_GetXMLintoAA(xml As Object, aa As Object)
      for each e in xml.GetBody()
          body = e.GetBody()
          if type(body) = "roString" or type(body) = "String" then
              name = e.GetName()
              name = AkaMA_strReplace(name, ":", "_")
              aa.AddReplace(name, body)
          endif
      next
  End Sub
  
  