parseCdxml function

StructurePage? parseCdxml(
  1. String xml
)

Implementation

StructurePage? parseCdxml(String xml) {
  XmlDocument document;
  try {
    document = XmlDocument.parse(xml);
  } catch (e) {
    return null;
  }
  int defaultLabelSize = join(
          int.tryParse,
          document
              .findElements('CDXML')
              .firstOrNull
              ?.getAttribute('LabelSize')) ??
      12;
  var fragments = <Fragment>[];
  var xmlfragments = document
      .findElements('CDXML')
      .firstOrNull
      ?.findElements("page")
      .firstOrNull
      ?.findElements('fragment');
  if (xmlfragments == null) return null;
  var pageBoundingBox = document
          .findAllElements('page')
          .first
          .getAttribute('BoundingBox')
          ?.split(' ')
          .map((e) => double.tryParse(e) ?? 0.0)
          .toList() ??
      [0, 0, 0, 0];

  for (var fragment in xmlfragments) {
    var xmlAtoms = fragment.findElements('n');
    var xmlBonds = fragment.findElements('b');
    var atoms = <Atom>[];
    var bonds = <Bond>[];
    for (var xmlAtom in xmlAtoms) {
      String? textId = xmlAtom.getAttribute('id');
      if (textId == null) return null;
      int id = int.tryParse(textId) ?? 0;
      double x =
          join(double.tryParse, xmlAtom.getAttribute('p')?.split(' ')[0]) ??
              0.0;
      double y =
          join(double.tryParse, xmlAtom.getAttribute('p')?.split(' ')[1]) ??
              0.0;
      String atomLabel =
          xmlAtom.getElement('t')?.getElement('s')?.innerText ?? "C";

      atoms.add(Atom(atomLabel, id, x, y, fontSize: defaultLabelSize));
    }
    for (var xmlBond in xmlBonds) {
      var beginAtom = join(int.tryParse, xmlBond.getAttribute('B')) ?? 0;
      var endAtom = join(int.tryParse, xmlBond.getAttribute('E')) ?? 0;
      var type = switch (xmlBond.getAttribute('Order')) {
        "1" => BondType.single,
        "2" => BondType.double,
        "3" => BondType.triple,
        _ => BondType.single
      };
      var position = switch (xmlBond.getAttribute("DoublePosition")) {
        "Left" => BondPosition.left,
        "Right" => BondPosition.right,
        "Center" => BondPosition.center,
        _ => BondPosition.unknown
      };
      bonds.add(Bond(BondStyle(bondType: type, bondPosition: position),
          beginAtom, endAtom));
    }
    List<double> a = fragment
            .getAttribute('BoundingBox')
            ?.split(' ')
            .map((e) => double.tryParse(e) ?? 0.0)
            .toList() ??
        [0, 0, 0, 0];
    fragments.add(Fragment(
        name: fragment.getAttribute('id') ?? "None",
        atoms: atoms.toSet(),
        bonds: bonds.toSet(),
        boundingBox: BoundingBox.fromDoublelist(a)));

    for (var bond in fragments.last.bonds) {
      if (bond.bondStyle.bondPosition == BondPosition.unknown) {
        bond.fixDoubleBondPosision(atoms.toSet(), bonds.toSet());
      }
    }
  }
  return StructurePage(
      name: "CDXML",
      fragments: fragments.toSet(),
      boundingBox: BoundingBox.fromDoublelist(pageBoundingBox));
}