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

发布时间:2026/9/29 11:34:43

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),仅供参考
延伸阅读

更多相关文章

2026/9/29 11:34:43

老电脑指南:可以装Win7系统CPU盘点

ㅤㅤ尽管Windows 7系统官方已停止支持多年,但鉴于目前还有很多工控软件对高版本系统的兼容性、以及特定办公需求和用户的操作习惯,Win7系统直至目前依然具有不可替代的使用价值。然而,随着硬件架构的快速迭代,新款处理器与Windows…

2026/9/29 11:29:42

用 scrcpy 在电脑上跑手机游戏:轻量安卓投屏与控制方案

用 scrcpy 在电脑上跑手机游戏:轻量安卓投屏与控制方案 【免费下载链接】scrcpy Display and control your Android device 项目地址: https://gitcode.com/GitHub_Trending/sc/scrcpy scrcpy 是一款开源的安卓投屏工具,能把手机画面镜像到电脑&a…

2026/9/29 12:29:46

你管这破玩意叫 MCP?用 TaoToken 统一 Key 打通 Cline 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/29 12:29:46

EtherCAT实时以太网:从站开发与多轴伺服同步实战

1. EtherCAT到底解决了什么问题搞工业自动化的朋友应该都有体会,早年间设备里跑的现场总线五花八门——Profibus DP、CANopen、Modbus RTU、DeviceNet……每家的PLC、伺服、变频器都有自己的脾气,想把不同品牌的设备拧到同一条总线上,经常得写…

2026/9/29 12:29:46

邮件安全四层防线:从账号加固到SPF/DKIM/DMARC部署

1. 邮件系统安全到底在防什么:先看清对手和战场1.1 一封邮件能捅多大娄子在动手加固之前,我建议大家先花几分钟想一想:邮箱里到底有什么值得被盯上?很多人觉得“我账号里没什么机密,黑客不会瞄上我”,这是我…

2026/9/29 12:29:46

常见网络攻击原理与防御:从SQL注入到DDoS的实战指南

简介:这是一份面向网络安全初学者、高校信息安全专业学生及安全培训学员的教学型PPT资料,系统梳理了最常见网络攻击的原理与防范手段。内容以典型攻击步骤为主线,覆盖预攻击探测、漏洞扫描、木马攻击、拒绝服务攻击、欺骗攻击、蠕虫病毒攻击等…

2026/9/29 11:07:23

东莞市品牌网站建设报价常见报错与解决

东莞品牌网站建设报价单背后:一份保姆级建站教程避坑实录 网站做好了没人访问,这大概是很多老板最头疼的事。花了大几万做的品牌站,上线后流量惨淡,比路边摊还冷清。别急着骂外包公司,很多“东莞品牌网站建设报价”里藏着不少猫腻,比如用模板站冒充定制…

2026/9/28 6:05:15

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/29 7:00:49

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/9/29 0:04:04

AI Evals实战指南:从零搭建LLM应用评估体系与CI/CD集成

1. 为什么AI Evals值得你花时间搞明白做LLM应用的人,迟早会撞上同一堵墙:模型输出飘忽不定,今天答得好好的,明天换个问法就胡说八道。你改了一版提示词,感觉好像好了点,但到底好了多少?说不清。…

2026/9/29 0:04:04

Java采购管理系统实战:从数据库设计到事务一致性

简介:这是一套面向Java Web初学者与课程设计者的采购管理系统完整源码,采用JSP技术搭建,配合MySQL数据库,用于解决企业采购信息的管理问题,适合作为毕业设计、课程大作业或进销存类项目的参考模板。系统实现了用户登录…

2026/9/29 3:53:39

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/29 9:46:12

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/29 6:36:14

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑