Ast: albero semantico del documento e serializzazione
In sintesi
Sezione intitolata “In sintesi”Il modulo Ast è l’albero semantico del documento usato dal motore. Modella un documento come una gerarchia di nodi tipizzati — Document, Section, Heading, Paragraph, List, Table, Figure, Code, FormField — con riquadri di delimitazione, ancore di citazione e serializzazione JSON versionata. Il livello di marcatura per l’accessibilità lo usa per produrre un albero di struttura.
Stabilità: sperimentale. Questa è una superficie di modello interna. Le sue classi non offrono garanzie di API pubblica con versione congelata; l’insieme dei nodi e i relativi attributi sono destinati a evolvere. Lo schema di serializzazione è versionato in modo indipendente (
AstDocument::CURRENT_SCHEMA_VERSION = '1.0.0'). Il serializzatore può rilevare e rifiutare uno schema incompatibile, così il JSON AST persistito mantiene un contratto stabile anche se l’API in memoria non offre la stessa garanzia.
Installazione
Sezione intitolata “Installazione”composer require nextpdf/core:^3Panoramica concettuale
Sezione intitolata “Panoramica concettuale”In questo contesto, un AST è un’astrazione semantica della struttura logica di un documento, non un albero sintattico di parsing legato a un singolo formato di input. AstDocument è il container. Contiene il AstNode radice (che deve essere NodeType::Document), una versione di schema, un hash del PDF di origine e un conteggio di pagine. Rifiuta costruzioni non valide (versione di schema vuota, conteggio di pagine inferiore a uno, tipo di radice errato).
AstNode è il nodo ricorsivo. NodeType enumera i tipi semantici. Un nodo contiene figli, un BoundingBox opzionale, contenuto testuale opzionale e attributi validati dallo schema tramite NodeAttributeSchema. L’API del nodo è progettata per la derivazione immutabile. withBboxAndText() restituisce un nuovo nodo. deepClone() copia un sottoalbero. NodeId rappresenta l’identità come oggetto-valore. CitationAnchor collega un nodo a una posizione di origine per la tracciabilità. AstNodeCollection è un insieme Countable/IteratorAggregate filtrabile tramite ofType().
AstSerializer è il confine di persistenza. serialize() scrive un AstDocument in JSON. deserialize() lo rilegge. canDeserialize() ed extractSchemaVersion() consentono a un consumatore di verificare la compatibilità prima del parsing, così una mancata corrispondenza di schema diventa una condizione rilevata anziché un caricamento corrotto. AstDocument::estimateTokenCount() esiste perché l’albero viene usato anche per dimensionare il contenuto destinato all’elaborazione a valle vincolata dai token.
Superficie API
Sezione intitolata “Superficie API”| Classe | Membri chiave | Ruolo |
|---|---|---|
AstDocument | toJson(), nodeCount(), estimateTokenCount(), CURRENT_SCHEMA_VERSION | Container radice; valida tipo di radice e schema |
AstNode | addChild(), children(), childCount(), totalNodeCount(), withBboxAndText(), deepClone() | Nodo semantico ricorsivo |
NodeType (enum) | Document, Heading, Table, Figure, FormField, … | Tipo di nodo semantico |
AstNodeCollection | add(), count(), isEmpty(), ofType(), toArray() | Insieme di nodi iterabile e filtrabile per tipo |
AstSerializer | serialize(), deserialize(), canDeserialize(), extractSchemaVersion() | Persistenza JSON versionata |
BoundingBox | toArray(), equals() | Oggetto-valore geometrico (confronto con epsilon) |
NodeId / CitationAnchor | toString(), equals(), toArray() | Identità del nodo e ancora di tracciabilità verso l’origine |
NodeAttributeSchema | validazione degli attributi | Schema per gli attributi dei nodi |
Eseguire composer docs:generate-api-php -- --module=Ast per la tabella PHPDoc completa.
Esempio di codice — Avvio rapido
Sezione intitolata “Esempio di codice — Avvio rapido”Costruire un piccolo albero e serializzarlo.
<?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 */);Esempio di codice — Produzione
Sezione intitolata “Esempio di codice — Produzione”Round-trip difensivo di un AST persistito, con verifica della compatibilità dello schema prima di deserializzare JSON non attendibile.
<?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); }}Casi limite e insidie
Sezione intitolata “Casi limite e insidie”AstDocumentrichiede che il nodo radice siaNodeType::Document. Un albero con qualsiasi altra radice solleva un’eccezione durante la costruzione.AstNode::withBboxAndText()edeepClone()restituiscono nuove istanze. I mutatori del nodo esistenti (addChild()) modificano lo stato. Gli helper di derivazione no. È importante sapere quale metodo si sta invocando.- Proteggere sempre
deserialize()concanDeserialize()per il JSON proveniente da fonti esterne. Una mancata corrispondenza della versione di schema è una condizione rilevabile e prevista. estimateTokenCount()è una stima per il dimensionamento dell’elaborazione a valle, non un conteggio esatto del tokenizzatore. Non trattarla come autorevole.BoundingBox::equals()è un confronto con epsilon (predefinito 0.001). L’uguaglianza esatta tra float non è il contratto.
Prestazioni
Sezione intitolata “Prestazioni”La costruzione e l’attraversamento dell’albero sono O(n) rispetto al conteggio dei nodi. La serializzazione è lineare rispetto alla dimensione dell’albero. Il profilo di riproducibilità è bitwise. Lo stesso albero viene serializzato negli stessi byte JSON: questo rende lo schema un contratto di persistenza stabile. Il carico di lavoro di riferimento predefinito rientra ampiamente nel budget di 1500 ms wall / 64 MB di picco.
Note sulla sicurezza
Sezione intitolata “Note sulla sicurezza”AstSerializer::deserialize() effettua il parsing di JSON che può essere persistito o trasmesso. Validare prima la compatibilità con canDeserialize(). Trattare il contenuto testuale e gli attributi dell’albero deserializzato come stringhe non attendibili quando rientrano nell’applicazione o vengono renderizzati. Il modulo stesso non esegue alcun I/O e non incorpora dati esterni. Vedere il modello di minaccia del motore in /modules/core/security/.
Conformità
Sezione intitolata “Conformità”Questo modulo non formula alcuna affermazione normativa su specifiche PDF. L’AST semantico è un’astrazione interna al motore. Non implementa un modello di documento standardizzato le cui clausole debbano essere citate. Quando l’AST alimenta la marcatura per l’accessibilità, la conformità PDF/UA e tagged-PDF dell’output è documentata e validata in /modules/core/accessibility/ e /modules/core/conformance/, non qui.
Vedere anche
Sezione intitolata “Vedere anche”- Modulo Accessibility — usa l’AST per costruire l’albero di struttura.
- Modulo Inspect — ispezione del layout e della struttura.
- Modulo HTML — fonte di struttura del documento.
- Panoramica sulla conformità