AST: Semantischer Dokumentbaum und Serialisierung
Auf einen Blick
Abschnitt betitelt „Auf einen Blick“Das AST-Modul bildet den semantischen Dokumentbaum der Engine. Es modelliert ein Dokument als typisierte Knotenhierarchie aus Document, Section, Heading, Paragraph, List, Table, Figure, Code, FormField mit Bounding-Boxen, Zitatankern und einer versionierten JSON-Serialisierung. Die Accessibility-Tagging-Schicht nutzt ihn, um einen Strukturbaum zu erzeugen.
Stabilität: experimentell. Dies ist eine interne Modelloberfläche. Ihre Klassen haben keine versionsfixierten Public-API-Garantien, und die Knotenmenge sowie die Knoten- attribute werden weiterentwickelt. Das Serialisierungsschema wird unabhängig versioniert (
AstDocument::CURRENT_SCHEMA_VERSION = '1.0.0'). Der Serializer kann ein inkompatibles Schema erkennen und ablehnen, sodass persistiertes AST-JSON einen stabilen Vertrag hat, auch wenn die In-Memory-API dies nicht garantiert.
Installation
Abschnitt betitelt „Installation“composer require nextpdf/core:^3Konzeptioneller Überblick
Abschnitt betitelt „Konzeptioneller Überblick“Ein AST ist hier eine semantische Abstraktion über die logische Struktur eines Dokuments und kein Parser-Syntaxbaum für ein einzelnes Eingabeformat. AstDocument ist der Container. Er enthält den Wurzel-AstNode (der NodeType::Document sein muss), eine Schemaversion, einen Quell-PDF-Hash und eine Seitenanzahl. Ungültige Konstruktionen lehnt er ab (leere Schemaversion, Seitenanzahl unter eins, falscher Wurzeltyp).
AstNode ist der rekursive Knotentyp. NodeType zählt die semantischen Arten auf. Ein Knoten enthält Kindknoten, eine optionale BoundingBox, optionalen Textinhalt und schemavalidierte Attribute über NodeAttributeSchema. Die Knoten-API ist auf unveränderliche Ableitungen ausgelegt. withBboxAndText() gibt einen neuen Knoten zurück. deepClone() kopiert einen Teilbaum. NodeId ist die Value-Object-Identität. CitationAnchor verknüpft einen Knoten zur Nachverfolgbarkeit mit einem Quellort. AstNodeCollection ist eine Countable-/IteratorAggregate-Sammlung mit ofType()-Filterung.
AstSerializer bildet die Persistenzgrenze. serialize() schreibt ein AstDocument als JSON. deserialize() liest es zurück. canDeserialize() und extractSchemaVersion() ermöglichen Konsumenten, die Kompatibilität vor dem Parsen zu prüfen, sodass eine Schemadiskrepanz eine erkannte Bedingung ist und kein beschädigter Ladevorgang. AstDocument::estimateTokenCount() existiert, weil der Baum auch dazu dient, Inhalte für die nachgelagerte tokenbegrenzte Verarbeitung zu dimensionieren.
API-Oberfläche
Abschnitt betitelt „API-Oberfläche“| Klasse | Wichtige Member | Rolle |
|---|---|---|
AstDocument | toJson(), nodeCount(), estimateTokenCount(), CURRENT_SCHEMA_VERSION | Wurzelcontainer; validiert Wurzeltyp und Schema |
AstNode | addChild(), children(), childCount(), totalNodeCount(), withBboxAndText(), deepClone() | Rekursiver semantischer Knoten |
NodeType (Enum) | Document, Heading, Table, Figure, FormField, … | Semantische Knotenart |
AstNodeCollection | add(), count(), isEmpty(), ofType(), toArray() | Iterierbare, typgefilterte Knotenmenge |
AstSerializer | serialize(), deserialize(), canDeserialize(), extractSchemaVersion() | Versionierte JSON-Persistenz |
BoundingBox | toArray(), equals() | Geometrie-Value-Object (Epsilon-Vergleich) |
NodeId / CitationAnchor | toString(), equals(), toArray() | Knotenidentität und Quell-Nachverfolgbarkeitsanker |
NodeAttributeSchema | Attributvalidierung | Schema für Knotenattribute |
Führen Sie composer docs:generate-api-php -- --module=Ast aus, um die vollständige PHPDoc-Tabelle zu erhalten.
Codebeispiel — Schnellstart
Abschnitt betitelt „Codebeispiel — Schnellstart“Erstellen Sie einen kleinen Baum und serialisieren Sie ihn.
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Ast\AstNode;use NextPDF\Ast\AstSerializer;use NextPDF\Ast\NodeType;
$root = new AstNode(NodeType::Document);$heading = new AstNode(NodeType::Heading);$root->addChild($heading);$root->addChild(new AstNode(NodeType::Paragraph));
echo "Nodes: {$root->totalNodeCount()}\n";
$json = (new AstSerializer())->serialize(/* an AstDocument wrapping $root */);Codebeispiel — Produktion
Abschnitt betitelt „Codebeispiel — Produktion“Verarbeiten Sie persistierten AST defensiv im Round-Trip und prüfen Sie die Schemakompatibilität vor dem Deserialisieren nicht vertrauenswürdiger JSON-Daten.
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Ast\AstDocument;use NextPDF\Ast\AstSerializer;use Psr\Log\LoggerInterface;
final readonly class AstStore{ public function __construct( private AstSerializer $serializer, private LoggerInterface $logger, ) {}
public function load(string $json): ?AstDocument { if (!$this->serializer->canDeserialize($json)) { $this->logger->warning('AST JSON schema incompatible; rejected.', [ 'found_schema' => $this->serializer->extractSchemaVersion($json), 'expected' => AstDocument::CURRENT_SCHEMA_VERSION, ]);
return null; }
return $this->serializer->deserialize($json); }}Grenzfälle & Fallstricke
Abschnitt betitelt „Grenzfälle & Fallstricke“AstDocumenterfordert, dass der WurzelknotenNodeType::Documentist. Ein Baum mit einer anderen Wurzel wirft bei der Konstruktion.AstNode::withBboxAndText()unddeepClone()geben neue Instanzen zurück. Die vorhandenen Knotenmutatoren (addChild()) mutieren. Die Ableitungshelfer tun dies nicht. Achten Sie darauf, welche Methode Sie aufrufen.- Schützen Sie
deserialize()bei extern bezogenem JSON immer mitcanDeserialize(). Eine Schemaversionsdiskrepanz ist eine erkennbare, erwartete Bedingung. estimateTokenCount()ist eine Schätzung zur Dimensionierung der nachgelagerten Verarbeitung, keine exakte Tokenizer-Zählung. Behandeln Sie den Wert nicht als maßgeblich.BoundingBox::equals()ist ein Epsilon-Vergleich (Standard 0.001). Exakte Float-Gleichheit gehört nicht zum Vertrag.
Performance
Abschnitt betitelt „Performance“Baumkonstruktion und -traversierung sind O(n) in der Anzahl der Knoten. Die Serialisierung ist linear in der Baumgröße. Das Reproduzierbarkeitsprofil ist bitwise. Derselbe Baum wird zu denselben JSON-Bytes serialisiert, was das Schema zu einem stabilen Persistenzvertrag macht. Die standardmäßige Referenzlast liegt deutlich innerhalb des Budgets von 1500 ms Wall / 64 MB Peak.
Sicherheitshinweise
Abschnitt betitelt „Sicherheitshinweise“AstSerializer::deserialize() parst JSON, das persistiert oder übertragen worden sein kann. Validieren Sie die Kompatibilität zuerst mit canDeserialize(). Behandeln Sie Textinhalt und Attribute des deserialisierten Baums als nicht vertrauenswürdige Strings, wenn sie wieder in die Anwendung gelangen oder gerendert werden. Das Modul selbst führt keine I/O aus und bettet keine externen Daten ein. Siehe das Bedrohungsmodell der Engine in /modules/core/security/.
Konformität
Abschnitt betitelt „Konformität“Dieses Modul erhebt keinen normativen Anspruch im Sinne der PDF-Spezifikation. Der semantische AST ist eine Engine-interne Abstraktion. Er implementiert kein standardisiertes Dokumentmodell, dessen Klauseln zitiert werden müssten. Wo der AST das Accessibility-Tagging speist, werden die PDF/UA- und Tagged-PDF-Konformität der Ausgabe unter /modules/core/accessibility/ und /modules/core/conformance/ dokumentiert und validiert, nicht hier.
Siehe auch
Abschnitt betitelt „Siehe auch“- Accessibility-Modul — nutzt den AST, um den Strukturbaum aufzubauen.
- Inspect-Modul — Layout- und Strukturinspektion.
- HTML-Modul — eine Quelle der Dokumentstruktur.
- Konformitätsüberblick