`XmlFluentValidator`:代码优先的 XML 验证,贴近你的规则

发布: (2026年1月13日 GMT+8 02:17)
6 min read
原文: Dev.to

Source: Dev.to

RzR

传统 XML 验证的问题/难点

XSD 有其自身的优势,但也伴随真实的权衡:

  • 可读性低,发现性差。
  • 对跨元素或计算规则的表达能力有限。
  • 难以随应用逻辑一起演进。
  • 缺乏(或几乎没有)自然的业务层验证语义位置。

纯运行时验证通常导致:

  • 自定义 XPath 逻辑在项目间重复。
  • 没有可与消费者共享的正式模式。
  • 运行时与契约之间的验证行为不一致。

XmlFluentValidator 可以帮助您弥补这部分差距。

什么是 XmlFluentValidator

XmlFluentValidator 是一个 .NET Standard 2.0 库,允许您:

  • 使用流畅、强类型的 C# API 定义 XML 验证规则。
  • 在运行时验证 XML 文档并提供结构化的错误输出。
  • 为规则设置文档、严重性和消息。
  • 将模式验证与自定义运行时逻辑相结合。
  • 从规则生成 XSD 模式(已支持并在持续演进中)。

它将验证规则视为 一等代码工件,而不是静态 XML 文件。

核心设计原则

  1. 代码即真相
    验证规则写在 C# 中,和领域逻辑放在一起。没有在模式文件和运行时验证之间的重复。

  2. 流畅、意图驱动的 API
    规则读起来像 需求,而不是基础设施:

    • 哪个元素是必需的?
    • 适用哪些约束?
    • 为什么要有这条规则?
  3. 运行时 + 模式兼容
    规则在可能的情况下设计为能够干净地映射到 XSD 构造,同时在必要时仍然允许仅运行时的逻辑。

定义验证规则

库的核心是一个面向 路径、元素和属性 的流式构建器。

元素规则

var validator = new XmlFluentValidator()
    .ForPath("/order/id")
        .WithElementRequired("Order ID is required")
        .WithElementMatchesRegex(@"^\d+$", "Order ID must be numeric")
        .Done()
    .ForPath("/order/total")
        .WithElementInRange(0, 10000, true, "Total must be between 0 and 10000")
        .Done();

这清晰地表达了:

  • 元素必须存在。
  • 值必须符合特定格式。
  • 值必须在有效的数值范围内。

没有 XSD 语法。没有 XPath 样板代码。

属性验证

validator
    .ForPath("/order/items/item")
        .WithAttributeRequired("sku", "SKU is mandatory")
        .WithAttributeMatchesRegex("sku", @"^[A-Z0-9\-]+$")
        .WithAttributeInRange("quantity", 1, 100, true)
        .Done();

这避免了常见的 XSD 问题——属性规则难以阅读或分散。

基数、长度和唯一性

API 支持常见的结构约束:

  • 元素存在性(必需 / 可选)。
  • 最大出现次数。
  • 值长度(最小、最大、精确)。
  • 同级节点之间的唯一性。
  • 数据类型强制。
  • 可空(xs:nillable)控制。

所有这些都可以直接在代码中记录并提供错误信息。

自定义和全局规则

有些规则根本无法用 XSD 表达(例如跨元素逻辑、计算总额、文档级约束)。XmlFluentValidator 支持 全局规则

validator.GlobalRule(doc =>
{
    var items = doc.XPathSelectElements("/order/items/item");
    return items.Any();
}, "Order must contain at least one item");

这些规则:

  • 在运行时执行。
  • 参与同一验证管道。
  • 生成结构化的错误信息。
  • 可以与模式验证共存。

这也是该库最突出的差异化特性之一。

验证执行与结果

var result = validator.Validate(xDocument);

if (!result.IsValid)
{
    foreach (var error in result.Errors)
    {
        Console.WriteLine($"{error.Path}: {error.Message}");
    }
}

每个验证错误包括:

  • XML 路径。
  • 违规规则。
  • 配置的消息。
  • 严重性元数据。

这使得输出适用于:

  • API。
  • 日志记录。
  • 自动化测试。

XSD 模式生成

XmlFluentValidator 的一个关键目标是 从流式验证规则生成模式。可以将以下规则:

  • 必需的元素。
  • 数据类型。
  • 范围。
  • 枚举。
  • 文档注释。

输出为 XSD 表示。这使您能够:

  • 与外部系统共享契约。
  • 保持模式与运行时验证同步。
  • 避免维护两个平行的验证工件。

XmlFluentValidator 弥合了代码优先验证与契约优先模式生成之间的差距,为 XML 验证提供了唯一的真实来源。

How It Fits into Real Systems

XmlFluentValidator 在以下情况下特别有用:

  • XML 验证规则经常演变。
  • 需要在 XSD 能力之外强制业务逻辑。
  • 验证必须在运行时动态执行。
  • 仍需共享或记录模式(Schema)。
  • 验证逻辑应与应用代码一起,而不是静态文件。

典型使用场景包括:

  • 集成网关
  • 配置验证
  • ETL 流程
  • 传统 XML 现代化
  • 特定领域的 XML 格式

最后思考

XmlFluentValidator 并不试图取代 XSD。
它旨在使 XML 验证 更具表现力、易于维护,并且符合现代 .NET 开发者的思维方式

如果你也认同:

  • 验证规则应当像业务规则一样易读
  • 代码应当是主要的事实来源
  • 架构应当由生成,而不是手工编写

那么 XmlFluentValidator 值得关注。

🔗 Repository:

Back to Blog

相关文章

阅读更多 »