docs: def from_xml(xml):
          """
          Pick informations from :class:`.MARCXMLRecord` object and use it to
          build :class:`.SemanticInfo` structure.
  
          Args:
              xml (str/MARCXMLRecord): MarcXML which will be converted to
                  SemanticInfo. In case of str, ``<record>`` tag is required.
  
          Returns:
              structure: :class:`.SemanticInfo`.
          """
          hasAcquisitionFields = False
          acquisitionFields = []
          isClosed = False
          isSummaryRecord = False
          contentOfFMT = ""
          parsedSummaryRecordSysNumber = ""
          summaryRecordSysNumber = ""
  
          parsed = xml
          if not isinstance(xml, MARCXMLRecord):
              parsed = MARCXMLRecord(str(xml))
  
          # handle FMT record
          if "FMT" in parsed.controlfields:
              contentOfFMT = parsed["FMT"]
  
              if contentOfFMT == "SE":
                  isSummaryRecord = True
  
          if "HLD" in parsed.datafields or "HLD" in parsed.controlfields:
              hasAcquisitionFields = True
  
              if "STZ" in parsed.datafields:
                  acquisitionFields.extend(parsed["STZa"])
                  acquisitionFields.extend(parsed["STZb"])
  
          def sign_and_author(sign):
              """
              Sign is stored in ISTa, author's name is in ISTb.
  
              Sign is MarcSubrecord obj with pointers to other subrecords, so it
              is possible to pick references to author's name from signs.
              """
              return [sign.replace(" ", "")] + sign.other_subfields.get("b", [])
  
          # look for catalogization fields
          for orig_sign in parsed["ISTa"]:
              sign = orig_sign.replace(" ", "")  # remove spaces
  
              if sign.startswith("sk"):
                  hasAcquisitionFields = True
                  acquisitionFields.extend(sign_and_author(orig_sign))
  
          # look whether the record was 'closed' by catalogizators
          for status in parsed["BASa"]:
              if status == "90":
                  isClosed = True
  
          # if multiple PJM statuses are present, join them together
          status = "\n".join([x for x in parsed["PJMa"]])
  
          # detect link to 'new' record, if the old one was 'closed'
          if status.strip():
              summaryRecordSysNumber = status
              parsedSummaryRecordSysNumber = _parse_summaryRecordSysNumber(
                  summaryRecordSysNumber
              )
  
          return EPeriodicalSemanticInfo(
              hasAcquisitionFields=hasAcquisitionFields,
              acquisitionFields=acquisitionFields,
              isClosed=isClosed,
              isSummaryRecord=isSummaryRecord,
              contentOfFMT=contentOfFMT,
              parsedSummaryRecordSysNumber=parsedSummaryRecordSysNumber,
              summaryRecordSysNumber=summaryRecordSysNumber,
          )