ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Xberg Elixir 绑定实战:用 extract_async 与 ExtractInput 实现 PDF 文本提取

Xberg Elixir 绑定实战:用 extract_async 与 ExtractInput 实现 PDF 文本提取 后端AI 应用NLP【免费下载链接】xbergPolyglot document intelligence with a Rust core: extract text, metadata, images, tables, and structured data from 106 formats across 140 file extensions, plus code intelligence for 371 languages. Fifteen bindings, with CLI, REST API, and MCP server.项目地址https://gitcode.com/gh_mirrors/kr/xberg点击查看免费下载本篇指南聚焦于 Xberg 项目Polyglot document intelligenceRust 核心 多语言绑定中 Elixir 绑定最基础也最常用的一个场景对 PDF 文档执行纯文本提取并读取结果元数据。文章以仓库 docs-site 中为 Elixir 生成的format_pdf_text代码片段为主线逐行拆解Xberg.ExtractInput输入结构的每个字段、extract_async/1与高层extract/1两种调用形式、返回值results的结构并结合 fixtures/format_specific/format_pdf_text.json 夹具定义与 e2e/elixir/test/format_specific_test.exs 端到端测试说明该用例在仓库中的验证方式与底层调用链。读完你可以直接在 Elixir 工程中写出可运行、可验证的 PDF 文本提取代码。一段式 PDF 文本提取从一条调用开始仓库中的 Elixir 代码片段定义在 docs-site/src/snippets-generated/elixir/format_specific/format_pdf_text.md其标题即主题Standalone PDF text extraction using extract使用 extract 的独立 PDF 文本提取。核心代码只有几行input_value %Xberg.ExtractInput{filename: fake_memo.pdf, kind: uri, mime_type: application/pdf, uri: https://example.com/pdf/fake_memo.pdf} result Xberg.extract_async(input_value) IO.inspect(Enum.at(result.results, 0).metadata)这段代码做了三件事构造一个Xberg.ExtractInput结构体声明输入来源是一份名为fake_memo.pdf、MIME 类型为application/pdf、位于给定 URI 的 PDF 文档调用Xberg.extract_async/1发起提取取回结果列表results中第一个元素的metadata字段打印出来。该片段来自 docs-site 的 snippets-generated 目录属于 alef 自动生成的文档片段文件头标注This file is auto-generated by alef — DO NOT EDIT.可通过alef e2e generate重新生成、alef verify校验新鲜度。它看似极简背后却对应着仓库中一整套从输入结构到原生调用、再到端到端验证的实现下面逐层展开。输入结构 Xberg.ExtractInput 详解Xberg.ExtractInput定义在 packages/elixir/lib/xberg/extract_input.ex模块文档将其描述为Unified extraction input for all public extraction entry points所有公开提取入口的统一输入。其defstruct定义的字段如下字段类型默认值说明kindXberg.ExtractInputKind.t():uri输入来源类型示例使用:uri另有字节输入模式见下文bytesbinary() \| nilnil文档原始字节kind: :bytes时使用uriString.t() \| nilnil文档远程地址kind: :uri时使用mime_typeString.t() \| nilnil文档 MIME 类型示例为application/pdffilenameString.t() \| nilnil文件名影响格式探测与结果元数据configXberg.FileExtractionConfig.t() \| nilnil可选的提取配置输出格式、OCR、分块等示例片段中构造了filename、kind、mime_type、uri四个字段bytes与config保持默认nil。需要注意kind与uri的默认值使代码片段即便只写%Xberg.ExtractInput{uri: ...}也能按 URI 模式工作但显式声明mime_type: application/pdf能让下游格式分派更明确这也是 e2e 测试始终保留该字段的原因。该结构体还实现了Jason.Encoder编码时会先把结构体转为 map剔除所有值为nil的字段再交给 Jason 编码见 extract_input.ex 中defimpl Jason.Encoder的实现。这意味着发送给原生层的 JSON 只包含实际设置的字段未声明的输入项不会干扰格式探测。两种调用形式extract_async 与 extract代码片段直接调用的是Xberg.extract_async(input_value)。从源码结构看Xberg模块packages/elixir/lib/xberg.ex对外暴露了高层 API其中extract/1使用 Elixir 惯用的 keyword list 形式封装了底层调用doc Extract content from a single bytes or URI input. spec extract(keyword()) :: {:ok, map()} | {:error, atom, String.t()} def extract(opts \\ []) do Xberg.Native.extract_async( case Keyword.get(opts, :input) do nil - nil v when is_binary(v) - v v - Jason.encode!(v) end, case Keyword.get(opts, :config) do nil - nil v when is_binary(v) - v v - Jason.encode!(v) end ) end这段实现透露了两个关键事实Xberg.Native.extract_async/2是真正的原生Rust NIF入口接收序列化后的 JSON 字符串或nilextract/1负责把:input与:config两个 keyword 参数编码为 JSON 后转发非字符串结构体如%Xberg.ExtractInput{}会被Jason.encode!/1序列化。因此代码片段中的Xberg.extract_async(input_value)与仓库 e2e 测试中普遍使用的Xberg.extract(input: input_value)是同一能力的两种表达前者直接传入结构体由绑定层负责编码后者通过 keyword API 显式声明input键。e2e 测试 format_specific_test.exs 中 PDF 用例实际采用{:ok, result} Xberg.extract(input: input_value)并模式匹配返回值可见规范用法是接收{:ok, result}/{:error, reason, message}元组。返回值解析results、content 与 metadata片段用Enum.at(result.results, 0).metadata读取结果。这里result是提取响应其results字段为结果列表——尽管示例只输入了一个文档列表结构仍然保留便于与批量提取extract_batch共用同一套响应模型。每个结果元素至少包含content提取出的正文内容文本或结构化列表。夹具断言要求其长度不小于 50 字符可参考 fixtures/format_specific/format_pdf_text.json 中min_length断言的定义metadata与该文档相关的元数据示例直接IO.inspect打印它可用于核对文件名、来源、文档属性等信息。仓库中results[0].metadata与results[0].content的组合在多个 e2e 测试中被反复断言例如 e2e/elixir/test/contract_test.exs 中的批量与配置用例说明这是所有语言绑定通用的稳定契约。若需要校验提取出的正文是否包含某段原文可以对content做String.contains?/2检查这正是下面夹具断言的做法。测试夹具与断言format_pdf_text 到底在验证什么文档片段不是凭空而来它由 fixtures/format_specific/format_pdf_text.json 这个共享夹具驱动生成。该夹具完整定义了用例的行为契约category / idformat_specific分类下的format_pdf_text描述为Standalone PDF text extraction using extract标签pdf、text_extractioncallextract即提取入口input.extract_inputkind: uri、uri: $mock_url/pdf/fake_memo.pdf、mime_type: application/pdf、filename: fake_memo.pdf——与 Elixir 片段一一对应input.mock_responsesmock 服务器对路径/pdf/fake_memo.pdf返回 200content-type: application/pdf响应体来自一个样例备忘录 PDFbody_file指向 test_documents 下的fake_memo.pdfassertions断言not_error提取过程不得报错min_lengthresults[0].content长度不小于 50contains_anyresults[0].content中必须出现Mallori或May二者之一。这组断言说明“PDF 文本提取成功”在仓库中的客观标准不抛错、正文足够长、且确实提取出了样例文档中的真实人名文本。$mock_url是占位符运行时由测试基建替换为真实 mock 服务地址保证测试不依赖外部网络。同分类下还有其他格式的夹具docx、hwpx、pptx、xlsx说明format_specific是一组“按格式验证独立提取能力”的契约用例而format_pdf_text就是其中面向 PDF 的一份。E2E 测试验证与 mock 服务对应 Elixir 的端到端测试位于 e2e/elixir/test/format_specific_test.exs 的describe format_pdf_text块中input_mock_base_url System.get_env(MOCK_SERVER_FORMAT_PDF_TEXT) || #{System.get_env(MOCK_SERVER_URL)}/fixtures/format_pdf_text input_value %Xberg.ExtractInput{ filename: fake_memo.pdf, kind: uri, mime_type: application/pdf, uri: String.replace($mock_url/pdf/fake_memo.pdf, $mock_url, input_mock_base_url) } {:ok, result} Xberg.extract(input: input_value) assert (is_binary(Enum.at(result.results, 0).content) byte_size(Enum.at(result.results, 0).content) 50) || (is_list(Enum.at(result.results, 0).content) length(Enum.at(result.results, 0).content) 50) assert Enum.any?([Mallori, May], fn v - String.contains?(to_string(Enum.at(result.results, 0).content), v) end)测试要点mock 基址通过环境变量MOCK_SERVER_FORMAT_PDF_TEXT注入缺省时回退到MOCK_SERVER_URL/fixtures/format_pdf_text用String.replace($mock_url/..., $mock_url, base)完成占位符替换再构造ExtractInput断言与夹具严格一致content 长度 ≥ 50且包含Mallori或May。注意 content 可能是字符串也可能是列表对应不同输出格式因此测试对两种形态分别用byte_size与length判断。如果要在本地复现这段测试可按 scripts/e2e/run-with-mock-server.sh 提供的思路先启动 mock 服务器再设置MOCK_SERVER_URL运行 ExUnit 测试PDF 样例文档的字节输入变体可参考 e2e/elixir/test/extract_test.exs那里用bytes: :binary.bin_to_list(File.read!(pdf/fake_memo.pdf))直接读取本地文件。从 URI 到字节bytes 输入变体ExtractInput的kind字段默认是:uri但同一套提取链路也支持:bytes模式。在 e2e/elixir/test/extract_test.exs 中可以见到本地文件字节输入的写法bytes: :binary.bin_to_list(File.read!(pdf/fake_memo.pdf)), filename: fake_memo.pdf即把kind改为:bytes、填入bytes字段即可。这使 Elixir 绑定既能处理远程 URI示例场景也能处理本地读取的字节流二者共用同一个extract/extract_async入口与同一套results响应结构适合离线或内网环境下不经过 HTTP 的提取需求。底层实现视角Rust 核心调用链从源码结构可以梳理出这条调用链的完整形态Elixir 侧Xberg.extract_async/1或Xberg.extract/1→Xberg.Native.extract_async/2输入以 JSON 形式传入原生边界packages/elixir/lib/xberg/native.ex 声明了与 Rust 侧 NIF 对应的函数签名负责 FFI 桥接Rust 核心真正的文档解析发生在 crates 目录下的 Rust 工程中——crates/xberg的 src/extraction 目录包含提取入口与调度逻辑src/pdf与src/extractors等目录承载 PDF 解析器与格式分派。项目整体以 Rust 为内核通过 15 种绑定语言对外提供统一能力Elixir 绑定只是其中之一。理解这一链条有助于排查问题如果提取结果异常先检查输入 JSON 是否正确编码对应Jason.Encoder实现的nil过滤逻辑再确认 MIME 类型与文件名是否能让 Rust 侧正确分派到 PDF 提取器最后才需要深入到 Rust 解析层。常见问题与注意事项MIME 类型务必准确mime_type: application/pdf让格式分派直接命中 PDF 提取器缺失或错误可能触发内容嗅探行为取决于mime_detection_policy等配置见 packages/elixir/lib/xberg/mime_detection_policy.ex。URI 模式依赖网络可达kind: uri时提取器会请求该地址因此测试环境一律使用 mock 服务器替换$mock_url生产环境需确保目标 URI 可访问若文档敏感或需离线处理改用kind: bytes传入字节。配置如何传入ExtractInput的config字段或extract/1的:config关键字可携带output_format等提取选项。同目录的 docx 用例展示了字符串 JSON 配置的写法Xberg.extract(input: input_value, config: {\output_format\:\markdown\})PDF 场景同理可用。返回值匹配规范优先采用{:ok, result} Xberg.extract(input: input_value)的模式匹配形式如 format_specific_test.exs 所示并显式处理{:error, reason, message}分支。延伸阅读完整 Elixir 绑定说明packages/elixir/README.md高层 API 与全部入口函数packages/elixir/lib/xberg.ex输入结构定义packages/elixir/lib/xberg/extract_input.ex夹具契约定义fixtures/format_specific/format_pdf_text.jsonElixir 端到端测试e2e/elixir/test/format_specific_test.exsRust 核心提取实现crates/xberg/src/extraction赞分享后端AI 应用NLP【免费下载链接】xbergPolyglot document intelligence with a Rust core: extract text, metadata, images, tables, and structured data from 106 formats across 140 file extensions, plus code intelligence for 371 languages. Fifteen bindings, with CLI, REST API, and MCP server.项目地址https://gitcode.com/gh_mirrors/kr/xberg点击查看免费下载相关推荐Xberg Elixir 远程 URL 文档提取实战使用 extract_async 处理远程文本文档Xberg Elixir 远程 URL 文档提取实战使用 extract_async 处理远程文本文档 导读 本文围绕 Xberg 官方 Elixir 绑定中后端AI 应用NLPXberg Elixir URI 提取实战用 ExtractInput 从 HTTP(S) URL 与本地路径抽取文档内容Xberg Elixir URI 提取实战用 ExtractInput 从 HTTP S URL 与本地路径抽取文档内容 api_extract_uri 是后端AI 应用NLP使用 Xberg C 绑定提取 PDF 文本ExtractAsync 完整实战指南使用 Xberg C 绑定提取 PDF 文本ExtractAsync 完整实战指南 本文围绕 Xberg 官方 C 绑定中“独立 PDF 文本提取Stand后端AI 应用NLP上一篇ReVanced Integrations 完全指南掌握 YouTube 增强插件的核心组件库下一篇超级玛丽64物理碰撞机制全解析揭秘角色弹跳与滑行的底层逻辑创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表