Дмитрий
Дмитрий29. August 2017 15:26

Öffnen Sie fb2-Dateien mit Qt

Derzeit ist fb2 ein beliebtes Format zum Speichern von Büchern. Die fb2-Datei ist ein Sonderfall von xml. Das Hauptelement seiner Struktur ist, wie bei HTML, das Tag (Steuerwörter). In diesem Artikel zeige ich Ihnen, wie Sie einen einfachen fb2-Dateibetrachter erstellen. Das Projekt mit dem Quelltext kann unter dem link. heruntergeladen werden.

Allgemeine Information

Tags werden in Block- und Kleinbuchstaben unterteilt. Block-Tags werden paarweise gruppiert, beginnend mit dem öffnenden Tag, das das Tag schließt, zwischen dem sich der Inhalt befindet. Beispielsweise wird ein Textabschnitt geschrieben als

<p>Paragraph text</p>

Innerhalb eines solchen Blockpaars können Sie andere Tags einfügen. Kleinbuchstaben-Tags werden für Objekte verwendet, in die nichts eingebettet werden kann. Beispielsweise ein Zeiger auf eine Zeichnung

<image l:href = “#_0.jpg”/>

enthält Informationen: 1) dass an der angegebenen Stelle des Dokuments eine Zeichnung eingefügt werden muss, 2) einen Link zu dieser Abbildung. Der Algorithmus zum Einfügen eines Bildes in Text wird unten erklärt. Unterscheiden Sie 3 Arten von Tags einfach mit Hilfe eines Schrägstrichs. Beim Zeilen-Tag fehlt der Schrägstrich vor der schließenden Klammer, beim schließenden Block nach dem öffnenden, beim öffnenden Block fehlt er.

Wenn Sie es vollständig verstehen wollen, studieren Sie HTML. Es gibt einige Unterschiede zwischen HTML und fb2, obwohl sie in vielerlei Hinsicht identisch sind. Auf solche Elemente werde ich im Verlauf der Erzählung hinweisen. Beachten Sie auch, dass xml im Gegensatz zu html nicht die CSS-Sprache verwendet, in unserem Fall bedeutet dies, dass es in der fb2-Datei keinen Hinweis darauf gibt, wie der Text formatiert ist (Schriftgröße und -farbe, Absatzlayout usw.). All dies müssen wir (falls gewünscht) eigenständig umsetzen.

Struktur der fb2-Datei

Der erste<?xml> -Tag enthält technische Informationen über das Format, seine Version und die verwendete Kodierung. Das zweite Etikett umfasst das ganze Buch. In der Regel gibt es in jedem Buch 2 Teile: eine Beschreibung von und der Hauptteil von (wie in html). Die Beschreibung enthält den Namen des Autors, den Titel des Buchs, Anmerkungen usw. Der Hauptteil enthält die Titel (das ganze Buch oder einzelne Kapitel), Kapitel / Teile / Abschnitte <section> und Text <p> (wie in html).</html>

<?xml …>
  <FictionBook …>
    <description>
    …
    </description>
    <body>
    …
    </body>
  …
  </FictionBook>

Darüber hinaus finden Sie die Inschrift Tags, der Link (wie in HTML), die Bild und das Leere Zeile (in html
). Links können extern und intern sein. Externe Links enthalten als Parameter die Quell-URL, interne Links enthalten Verweise auf die Elemente im Text der Datei (siehe obiges Bild-Tag). Zeichnungen enthalten ähnliche interne Referenzen.

Nach dem

Abschnitt können zusätzliche Elemente lokalisiert werden. Also in getrennten Tags die in die Textform umgewandelten Bilder werden platziert.

Erstellen eines Leseprogramms

Wir werden unser Programm folgendermaßen erstellen: Wir lesen die Daten aus der Datei und konvertieren sie in HTML und senden dann die generierte Zeichenfolge mit der Funktion setHtml (QString) an das Textfeld. Ein kleiner Lifhack für diejenigen, die HTML lernen wollen: Das Klassenobjekt QTextEdit / QTextBrowser kann das formatierte Dokument als Quelltext anzeigen. Öffnen Sie dazu den Formulareditor, klicken Sie 2 mal auf das Objekt und wechseln Sie auf den Reiter „Quelle“.

Um fb2-Dateien zu verarbeiten, verwenden wir die Klasse QXmlStreamReader. Um damit zu arbeiten, müssen Sie die Module xml und xmlpatterns mit dem Projekt verbinden. Als Argument muss ihr ein Zeiger auf ein Objekt der Klasse QFile übergeben werden.

QFile f(name);
QXmlStreamReader sr(&f);

Das Öffnen der Datei selbst sieht aus wie ein Zyklus mit sequentiellem Lesen von Zeilen. Wir brauchen auch 3 Variablen

QString book;
QString imgId;
QString imgType;

book wird benötigt, um das generierte Dokument zu speichern, imgId und imgType zum Einfügen von Bildern in Text. Die QXmlStreamReader-Klasse erzeugt mehrere wichtige Aktionen. Zunächst ermittelt und installiert er den gewünschten Decoder. Zweitens trennt es die Tags vom Inhalt. Drittens hebt es die Eigenschaften von Tags hervor. Wir können nur die getrennten Daten verarbeiten. Die Funktion readNext () wird verwendet, um die Daten zu lesen. Alle darin gelesenen Fragmente gehören zu einem von 5 Typen: StartDocument, EndDocument, StartElement, EndElement und Characters. Davon bestimmen 2 als erste den Anfang und das Ende der Datei, 2 lesen als nächste die Tags und erhalten als letzte den Platzhalter.

Nachdem wir StartDocument erhalten haben, müssen wir die Kopfzeile des HTML-Dokuments und 2 öffnende Tags hinzufügen

book = "<!DOCTYPE HTML><html><body style=\"font-size:14px\">";

Wenn EndDocument erreicht ist, schließen wir die am Anfang der Datei geöffneten Tags

book.append("</body></html>");

Das Erscheinen von StartElement bedeutet, dass das öffnende oder Kleinbuchstaben-Tag gelesen wird. Dementsprechend signalisiert EndElement das Lesen des schließenden Tags. Der Name des Tags wird durch Aufruf der Funktion sr.name() ermittelt. ToString (). Um die Struktur des Dokuments zu steuern, speichern wir eine Liste aller offenen Tags im Objekt thisToken der Klasse QStringList. Hängt daher im Fall von StartElement den Namen des aktuellen Tags an thisToken an und löscht ihn im Fall von EndElement. Außerdem können die öffnenden Tags (oder Kleinbuchstaben) Attribute enthalten. Das Attribut wird gelesen und in sr als Array von Strings gespeichert. Sie können mit der Methode sr.attributes () darauf zugreifen. Wir brauchen sie, um Bilder zum Text hinzuzufügen. Wenn also ein Tag gefunden wird, müssen Sie dem Bild im Text ein Label hinzufügen.

book.append("<p align=\"center\">"+sr.attributes().at(0).value().toString()+"</p>");

Dann, wenn wir die finden -Tag, müssen wir dessen Tag und Format speichern.

imgId = sr.attributes().at(0).value().toString();
imgType = sr.attributes().at(1).value().toString();

Beachten Sie, dass die imgId mit der identisch ist tag-Attribut, mit Ausnahme des fehlenden Kreuzzeichens (#).

Jetzt können wir den Inhalt nur noch in das Streichbuch stellen. Hier können Sie ein anderes Regelwerk verwenden. Ignoriere zum Beispiel die Beschreibung eines Buches

if(thisToken.contains("description"))
{
    break; // не выводим
}

oder markieren Sie die Überschriften durch Farbe, Schriftgröße und Typ. Bleiben wir nur bei den Bildern. Um sie einzufügen, müssen Sie eine Zeichenfolge vom Typ bilden

QString image = "<img src=\"data:"
        + imgType +";base64,"
        + sr.text().toString()
        + "\"/>";

wo sr.text (). toString () enthält den Inhalt der Schild. Dann sollten Sie in unserem Zeilendokument die dieser Abbildung entsprechende Beschriftung auf dieser Zeile ersetzen

book.replace("#"+imgId, image);

Der Algorithmus zum Lesen der fb2-Datei

    while( !sr.atEnd() )
    {
        switch( sr.readNext() )
        {
        case QXmlStreamReader::NoToken:
            qDebug() << "QXmlStreamReader::NoToken";
            break;
        case QXmlStreamReader::StartDocument:
            book = "<!DOCTYPE HTML><html><body style=\"font-size:14px\">";
            break;
        case QXmlStreamReader::EndDocument:
            book.append("</body></html>");
            break;
        case QXmlStreamReader::StartElement:
            thisToken.append( sr.name().toString() );
            if( sr.name().toString() == "image" ) // расположение рисунков
            {
                if(sr.attributes().count() > 0)
                    book.append("<p align=\"center\">"+sr.attributes().at(0).value().toString()+"</p>");
            }
            if(sr.name() == "binary") // хранилище рисунков
            {
                imgId = sr.attributes().at(0).value().toString();
                imgType = sr.attributes().at(1).value().toString();
            }
            break;
        case QXmlStreamReader::EndElement:
            if( thisToken.last() == sr.name().toString() )
                thisToken.removeLast();
            else
                qDebug() << "error token";
            break;
        case QXmlStreamReader::Characters:
            if( sr.text().toString().contains( QRegExp("[A-Z]|[a-z]|[А-Я]|[а-я]") )) // если есть текст в блоке
            {
                if(thisToken.contains("description")) // ОПИСАНИЕ КНИГИ
                {
                    break; // не выводим
                }
                if(thisToken.contains("div"))
                    break;
                if(!thisToken.contains( "binary" ))
                    book.append("<p>" + sr.text().toString() + "</p>");
            }
            if(thisToken.contains( "binary" ) )//для рисунков
            {
                QString image = "<img src=\"data:"
                        + imgType +";base64,"
                        + sr.text().toString()
                        + "\"/>";
                book.replace("#"+imgId, image);
            }
            break;
        }
    }

Unser Dokument ist fertig. Es bleibt nur noch, die generierte Zeichenfolge in das Textfeld einzugeben

ui->textBrowser->setHtml(book);

Für die volle Arbeit des fb2-Readers müssen Sie Verarbeitungslinks, Tabellen und einige andere Objekte hinzufügen. Aber das obige Material reicht aus, um die Hauptinhalte des Buches zu extrahieren.

Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Stabiles Hosting des sozialen Netzwerks EVILEG. Wir empfehlen VDS-Hosting für Django-Projekte.

Magst du es? In sozialen Netzwerken teilen!

Kommentare

Nur autorisierte Benutzer können Kommentare posten.
Bitte Anmelden oder Registrieren
Letzte Kommentare
A
ALO1ZE19. Oktober 2024 08:19
Fb3-Dateileser auf Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Игорь Максимов5. Oktober 2024 07:51
Django – Lektion 064. So schreiben Sie eine Python-Markdown-Erweiterung Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas55. Juli 2024 11:02
QML - Lektion 016. SQLite-Datenbank und das Arbeiten damit in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
k
kmssr8. Februar 2024 18:43
Qt Linux - Lektion 001. Autorun Qt-Anwendung unter Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
Qt WinAPI - Lektion 007. Arbeiten mit ICMP-Ping in Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
Jetzt im Forum diskutieren
J
JacobFib17. Oktober 2024 03:27
добавить qlineseries в функции Пользователь может получить любые разъяснения по интересующим вопросам, касающимся обработки его персональных данных, обратившись к Оператору с помощью электронной почты https://topdecorpro.ru…
JW
Jhon Wick1. Oktober 2024 15:52
Indian Food Restaurant In Columbus OH| Layla’s Kitchen Indian Restaurant If you're looking for a truly authentic https://www.laylaskitchenrestaurantohio.com/ , Layla’s Kitchen Indian Restaurant is your go-to destination. Located at 6152 Cleveland Ave, Colu…
КГ
Кирилл Гусарев27. September 2024 09:09
Не запускается программа на Qt: точка входа в процедуру не найдена в библиотеке DLL Написал программу на C++ Qt в Qt Creator, сбилдил Release с помощью MinGW 64-bit, бинарнику напихал dll-ки с помощью windeployqt.exe. При попытке запуска моей сбилженной программы выдаёт три оши…
F
Fynjy22. Juli 2024 04:15
при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …

Folgen Sie uns in sozialen Netzwerken