Hallo Ralf, hab deinen Code mal etwas näher unter die Lupe genommen, weil ich eine Anwendung entwickle, die Epubs in einer Datenbank verwalten soll. Dabei ist mir folgende Ungereimtheit aufgefallen:
Delphi-Quellcode:
try
index := KAZip1.Entries.IndexOf(cr.opfFile);
//auch hier habe ich die Datei content.opf in einen Stream cr.ms eingelesen.
//Alternativ ist das epub-Archiv vielleicht aber auch schon entpackt
KAZip1.ExtractToStream(KAZip1.Entries.Items[
Index], cr.ms);
if index < 0
then exit;
// Test von index erst nach der Verwendung???
KaZip1.Active := true;
cr.ms.seek(0,sofromBeginning);
//so kann man einen Stream in eine string-Variable übergeben. s bzw cr.opfContent wird aber nur zum testen benötigt
SetString(s, PAnsiChar(cr.ms.Memory), cr.ms.Size);
{set string to get memory}
cr.opfContent := s;
//hier wird der Stream in den Xml-Parser übergeben
XmlDoc := TXMLDocument.Create(Application);
XmlDoc.Active := True;
XmlDoc.LoadFromStream(cr.ms);
cr.ms.Clear;
finally
end;
Die Integer-Variable
index wird erst nach ihrer Verwendung daraufhin überprüft, ob sie kleiner als 0 ist. Das halte ich für einen Fehler bzw. würde bei Nichtauffinden von "content.opf" (oder wie die Datei im Zip-Archiv auch heißen mag) eine Zugriffsverletzung auslösen, da ein Item mit einem Index kleiner 0 nicht existieren kann.
Des weiteren fand ich einen vollkommen unverständlichen Vergleich mit null im Abschnitt Metadata durchsuchen:
Delphi-Quellcode:
if ChildNodes[h].NodeName = 'meta' then
if (ChildNodes[h].Attributes['name']<>null)
and (ChildNodes[h].Attributes['name'] = 'cover')
then cr.mcover := ChildNodes[h].Attributes['content'];
Wozu hier ein Vergleich mit null, der zudem einen Compilerfehler erzeugt (was soll das sein: null?), nötig sein sollte, wo doch anschließend sowieso getestet wird, ob der Attribut-Name mit dem String 'cover' identisch ist, kann ich nicht nachvollziehen. Wenn dort 'cover" drinsteht, kann es ja nicht leer sein, oder?
Im Abschnitt
Guide reference durchsuchen kann ich nicht nachvollziehen, wieso mehrmals dieselben Childnodes abgerufen werden:
Delphi-Quellcode:
for z := 0 to XmlDoc.DocumentElement.ChildNodes['guide'].ChildNodes.Count - 1 do
begin
shref := XmlDoc.DocumentElement.ChildNodes['guide'].ChildNodes['reference'].AttributeNodes['href'].Text;
stitle := XmlDoc.DocumentElement.ChildNodes['guide'].ChildNodes['reference'].AttributeNodes['title'].Text;
stype := XmlDoc.DocumentElement.ChildNodes['guide'].ChildNodes['reference'].AttributeNodes['type'].Text;
end;
Die Zähl-Variable z wird nirgendwo verwendet, um auf den nächsten
Reference-Node zuzugreifen. Soweit ich das anhand meiner hier verfügbaren Epubs beurteilen kann, besitzt
guide stets ein odere mehrere Child-Nodes namens
reference, die jeweils drei Attribute enthalten. Müßte es dann nicht so geschrieben werden:
Delphi-Quellcode:
for z := 0 to XmlDoc.DocumentElement.ChildNodes['guide'].ChildNodes.Count - 1 do
if XmlDoc.DocumentElement.ChildNodes['guide'].ChildNodes[z].name = 'reference' Then
begin
shref := XmlDoc.DocumentElement.ChildNodes['guide'].ChildNodes[z].AttributeNodes['href'].Text;
stitle := XmlDoc.DocumentElement.ChildNodes['guide'].ChildNodes[z].AttributeNodes['title'].Text;
stype := XmlDoc.DocumentElement.ChildNodes['guide'].ChildNodes[z].AttributeNodes['type'].Text;
end;
Schleierhaft ist mir auch, was mit den Strings, die den lokalen Variablen
shref,
stitle und
stype zugewiesen wurden, geschehen soll. In deinem Code werden diese Variablen bis zum Ende der Procedure nicht mehr verwendet.
Ach ja, ich verwende selbstverständlich
Abbrevia statt
KaZip und bin gerade dabei, deine ellenlangen (und damit unübersichtlichen) Methoden in kleinere Häppchen auftzuteilen. Ansonsten: gute Arbeit (soweit ich das bislang zu beurteilen vermag) oder besser: Vorarbeit