Ast:語意文件樹與序列化
快速一覽
標題為「快速一覽」的區段Ast 模組提供引擎使用的語意文件樹。它會將文件建模為具型別的節點階層,包括 Document、Section、Heading、Paragraph、List、Table、Figure、Code、FormField,並包含定界框、引文錨點,以及具版本控管的 JSON 序列化。無障礙標記層會用它產生結構樹。
穩定度:實驗性。 這是內部模型介面。各類別並不承載已凍結版本的公開 API 保證,節點集合與節點屬性也會持續演進。不過,序列化結構描述會獨立進行版本控管 (
AstDocument::CURRENT_SCHEMA_VERSION = '1.0.0')。序列化器能偵測並拒絕不相容的結構描述,因此即使記憶體內 API 並不穩定, 持久化的 AST JSON 仍有穩定契約。
composer require nextpdf/core:^3概念總覽
標題為「概念總覽」的區段此處的 AST 是文件邏輯結構的語意抽象,而不是針對單一輸入格式的剖析語法樹。AstDocument 是容器,持有根 AstNode(必須是 NodeType::Document)、結構描述版本、來源 PDF 雜湊值與頁數。它會拒絕無效建構(結構描述版本為空、頁數小於一、根型別錯誤)。
AstNode 是遞迴節點。NodeType 列舉各種語意種類。節點會帶有子節點、選用的 BoundingBox、選用的文字內容,以及透過 NodeAttributeSchema 進行結構描述驗證的屬性。節點 API 是為不可變衍生設計。withBboxAndText() 會回傳新節點。deepClone() 會複製子樹。NodeId 是代表身分的值物件。CitationAnchor 會將節點繫結到來源位置,以便追溯。AstNodeCollection 是 Countable/IteratorAggregate 集合,並支援使用 ofType() 過濾。
AstSerializer 是持久化邊界。serialize() 會將 AstDocument 寫成 JSON。deserialize() 會把它讀回來。canDeserialize() 與 extractSchemaVersion() 讓使用端能在剖析前先檢查相容性,因此結構描述不符會被偵測出來,而不是變成一次損毀的載入。AstDocument::estimateTokenCount() 之所以存在,是因為這棵樹也用於為下游受 token 數量限制的處理估算內容大小。
API 介面
標題為「API 介面」的區段| 類別 | 主要成員 | 角色 |
|---|---|---|
AstDocument | toJson(), nodeCount(), estimateTokenCount(), CURRENT_SCHEMA_VERSION | 根容器;驗證根型別與結構描述版本 |
AstNode | addChild(), children(), childCount(), totalNodeCount(), withBboxAndText(), deepClone() | 遞迴語意節點 |
NodeType(列舉) | Document, Heading, Table, Figure, FormField, … | 語意節點種類 |
AstNodeCollection | add(), count(), isEmpty(), ofType(), toArray() | 可疊代、可依型別過濾的節點集合 |
AstSerializer | serialize(), deserialize(), canDeserialize(), extractSchemaVersion() | 具版本控管的 JSON 持久化 |
BoundingBox | toArray(), equals() | 幾何值物件(epsilon 比較) |
NodeId / CitationAnchor | toString(), equals(), toArray() | 節點身分與來源可追溯性錨點 |
NodeAttributeSchema | 屬性驗證 | 節點屬性的結構描述 |
執行 composer docs:generate-api-php -- --module=Ast 即可取得完整 PHPDoc 表格。
程式碼範例 —— 快速開始
標題為「程式碼範例 —— 快速開始」的區段建立一棵小型樹,並將它序列化。
<?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 */);程式碼範例 —— 正式環境
標題為「程式碼範例 —— 正式環境」的區段在反序列化不受信任的 JSON 前,先檢查結構描述相容性,並以防禦性方式處理持久化 AST 的往返流程。
<?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); }}邊界情況與陷阱
標題為「邊界情況與陷阱」的區段AstDocument要求根節點必須是NodeType::Document。若以任何其他型別作為根,建構時都會擲出例外。AstNode::withBboxAndText()與deepClone()會回傳新的實例。節點變動方法(addChild())會就地修改既有實例;衍生輔助方法則不會。請確認自己呼叫的是哪一種。- 對於外部來源的 JSON,請務必以
canDeserialize()來把關deserialize()。結構描述版本不符是可偵測且預期中的狀況。 estimateTokenCount()是用來為下游處理估算大小的估計值,並非精確的 tokenizer 計數。請勿將它視為權威依據。BoundingBox::equals()是一種 epsilon 比較(預設 0.001)。精確的浮點相等並非其契約。
樹的建構與走訪複雜度相對於節點數量為 O(n)。序列化也與樹大小呈線性關係。它的可重現性設定檔為 bitwise。同一棵樹會序列化成相同的 JSON 位元組,這也是結構描述能成為穩定持久化契約的原因。預設參考工作負載遠低於 1500 ms 牆鐘時間 / 64 MB 峰值預算。
安全性注意事項
標題為「安全性注意事項」的區段AstSerializer::deserialize() 所剖析的 JSON 可能曾被持久化或傳輸。請先以 canDeserialize() 驗證相容性。當反序列化後樹中的文字內容與屬性再次進入應用程式或被算繪時,請將它們視為不受信任的字串。此模組本身不進行任何 I/O,也不內嵌任何外部資料。請參閱 /modules/core/security/ 中的引擎威脅模型。
符合性
標題為「符合性」的區段此模組不對任何 PDF 規格提出規範性聲明。此語意 AST 是引擎內部抽象。它並未實作任何必須引用其條款的標準化文件模型。當 AST 餵入無障礙標記時,其輸出的 PDF/UA 與標記式 PDF 符合性會記錄並驗證於 /modules/core/accessibility/ 與 /modules/core/conformance/,而非此處。
另請參閱
標題為「另請參閱」的區段- 無障礙模組 —— 使用 AST 建構結構樹。
- Inspect 模組 —— 版面與結構檢視。
- HTML 模組 —— 文件結構的來源之一。
- 符合性總覽