parsePackage function
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,
);
}
}