parsePackage function

EpubPackage parsePackage(
  1. String xml
)

Parses the provided XML string into an EpubPackage.

The function first parses the XML string into an XML document, then retrieves the package element from the document. It then retrieves the version, metadata, manifest, and spine from the package element. Depending on the version, it either creates an Epub2Package or an Epub3Package from the retrieved data.

xml is the XML string to parse.

Returns an EpubPackage representing the parsed package.

Throws an EpubException if the TOC ID is empty when creating an Epub3Package.

Implementation

EpubPackage parsePackage(final String xml) {
  final document = XmlDocument.parse(xml);
  final namespaceUri = document.rootElement.namespaceUri;

  final package = document
      .findElements(
        'package',
        namespace: namespaceUri,
      )
      .firstOrNull;
  _validate(package, 'package');
  final version = package!.getAttribute('version')?.trim() ?? '2.0';

  final metadataElement = package
      .findElements(
        'metadata',
        namespace: namespaceUri,
      )
      .firstOrNull;
  _validate(metadataElement, 'metadata');

  final manifestElement = package
      .findElements(
        'manifest',
        namespace: namespaceUri,
      )
      .firstOrNull;
  _validate(manifestElement, 'manifest');
  final spineElement = package
      .findElements(
        'spine',
        namespace: namespaceUri,
      )
      .firstOrNull;
  _validate(spineElement, 'spine');

  final uniqueIdentifierProperty = package.getAttribute(
        'unique-identifier',
      ) ??
      'uuid_id';

  final metadata = _parseMetadata(
    metadataElement!,
    version,
    uniqueIdentifierProperty,
  );
  final manifestItems = _parseManifestItems(manifestElement!, namespaceUri);
  final spine = _parseSpine(spineElement!);

  final xmlns = package.getAttribute('xmlns');
  if (_isEpub2(version)) {
    final guideElement = package
        .findElements(
          'guide',
          namespace: namespaceUri,
        )
        .firstOrNull;
    final guide = guideElement != null ? _parseGuide(guideElement) : null;

    return Epub2Package(
      xmlns: xmlns,
      uniqueIdentifier: uniqueIdentifierProperty,
      version: version,
      metadata: metadata,
      manifest: Epub2Manifest(items: manifestItems),
      spine: spine,
      guide: guide,
    );
  } else {
    final tocElement = manifestElement.findElements('item').firstWhereOrNull(
          (final element) =>
              element.getAttribute('properties')?.contains('nav') == true,
        );

    final tocPath = tocElement?.getAttribute('id') ?? spine.tocId;
    if (tocPath == null) {
      throw EpubException('EPUB parsing package error: TOC ID is empty.');
    }

    return Epub3Package(
      xmlns: xmlns,
      uniqueIdentifier: uniqueIdentifierProperty,
      version: version,
      metadata: metadata,
      manifest: Epub2Manifest(items: manifestItems),
      spine: spine,
      tocId: tocPath,
    );
  }
}