Hóa đơn và biên lai có chung một lối vào. Làm thế nào để tránh trộn lẫn hai cấu trúc?
Một giao diện nhận cả hóa đơn và biên lai, đồng thời thật dễ dàng viết các đối tượng lớn với "tất cả các trường tùy chọn". Một vật thể như vậy có thể chứa bất cứ thứ gì, nhưng rất khó để biết chính xác nó được nhận là gì. Sẽ rõ ràng hơn nếu giữ hai hợp đồng riêng biệt và chọn một trong số chúng có trường loại rõ ràng.
Hóa đơn và biên lai thường được đưa vào cùng một giao diện để xử lý, nhưng nếu chỉ sử dụng một đối tượng rộng có "tất cả các trường tùy chọn" để nhận thì nó có thể chứa bất kỳ đầu vào nào, nhưng nó không thể cho biết loại tài liệu nào được nhận. Bài viết này dành cho các nhà phát triển và nhân viên kinh doanh cần thiết kế giao diện nhận tài liệu hoặc duy trì các quy tắc xác thực Lược đồ JSON. Sau khi đọc phần này, bạn sẽ tìm hiểu cách giữ hai hợp đồng độc lập, chọn một hợp đồng có trường loại rõ ràng và xử lý xung đột nhánh cũng như các loại không xác định.
Các ví dụ trong bài viết này sử dụng các mẫu tổng hợp để minh họa các phương pháp xử lý. Mã đã được kiểm tra bằng các ví dụ trong môi trường biệt lập, nhưng điều này không đảm bảo cho tất cả các tệp thực hoặc hiệu suất sản phẩm. Trước khi xử lý các văn bản quan trọng, vui lòng giữ lại bản chính và xem xét theo ranh giới và các mục chấp nhận trong văn bản.
Xử lý thế nào khi hóa đơn, biên lai bị nhập chung? Một câu kết luận
Khi nhận được hai tài liệu từ cùng một cổng, sẽ rõ ràng hơn nếu giữ hai hợp đồng riêng biệt và sử dụng trường kind bắt buộc để chọn một trong số chúng, thay vì sử dụng một đối tượng rộng có thể chứa mọi thứ.
| hoàn cảnh của bạn | Các phương pháp được đề xuất | lý do |
|---|---|---|
| Giao diện tương tự cần nhận hóa đơn, biên lai | Giữ hai hợp đồng riêng biệt, được chọn với trường loại bắt buộc | Một đối tượng lớn với tất cả các trường tùy chọn có thể chứa bất kỳ thứ gì, nhưng rất khó để giải thích những gì được nhận. |
| Tổ chức các nhánh với oneOf | Mỗi nhánh sử dụng const để sửa loại | oneOf yêu cầu khớp chính xác một nhánh. Các trường nhánh chồng chéo sẽ khiến đầu vào hợp pháp không thành công. |
| Nhập thiếu loại hoặc xung đột trường | Trả về thông báo lỗi rõ ràng hiển thị các trường và nguồn xung đột | Chỉ hiển thị "không khớp" không thể giúp xác định vấn đề |
| Trình phân loại không thể phân biệt giữa các loại tài liệu | Giữ lại trạng thái không xác định và vào hàng đợi độc lập để được phân loại | Chọn ngẫu nhiên một nhánh sẽ chỉ tạo ra "thành công" giả |
| Xác minh cấu trúc đã được thông qua | Điều đó không có nghĩa là việc phân loại là chính xác, cũng không có nghĩa là các tài liệu đó là xác thực. | Độ tin cậy phân loại, xác minh cấu trúc và tính xác thực của doanh nghiệp là ba cấp độ khác nhau |
Tại sao bạn không thể sử dụng một đối tượng rộng?
Nguy cơ khiến tất cả các trường trở thành tùy chọn
Khi một giao diện chấp nhận cả hóa đơn và biên lai, bạn có thể dễ dàng viết các đối tượng lớn với "tất cả các trường tùy chọn". Một đối tượng như vậy thực sự có thể nhận được nhiều loại đầu vào khác nhau, nhưng với cái giá phải trả là:
- Không thể biết từ cấu trúc tài liệu nào được nhận.
- Các mục bắt buộc và mục tùy chọn của hai loại văn bản này bị trộn lẫn với nhau, quy định xác minh ngày càng mờ nhạt.
- Khi xảy ra lỗi khó có thể giải thích chính xác đầu vào không như mong đợi ở đâu.
Sẽ rõ ràng hơn nếu giữ hai hợp đồng riêng biệt và chọn một trong số chúng có trường loại rõ ràng.
oneOf không phải là bất kỳ ai
Các nhánh chồng lấn có thể gây ra lỗi đầu vào hợp lệ
oneOf yêu cầu đầu vào phải khớp chính xác một nhánh. Nếu cả hai nhánh đều vượt qua đồng thời, việc xác thực tổng thể cũng sẽ thất bại.
Nếu một nhánh chỉ chứa một vài trường tùy chọn, chúng có khả năng chồng lấn rộng rãi. Ở thời điểm này, đầu vào hợp lệ thực sự không vượt qua được xác minh.
Sử dụng kind và const để loại bỏ sự chồng chéo
Bằng cách sử dụng trường kind cần thiết cộng với const để cố định giá trị, bạn có thể thiết lập ranh giới rõ ràng giữa các nhánh và loại bỏ sự chồng chéo này từ trước.
Để biết thêm chi tiết về các quy tắc kết hợp, hãy tham khảo Quy tắc kết hợp Lược đồ JSON.
Giao thức chuyển hướng thực thi
from jsonschema import Draft202012Validator
def branch(kind, identity):
return {
"type": "object", "additionalProperties": False,
"required": ["kind", identity],
"properties": {"kind": {"const": kind},
identity: {"type": "string", "minLength": 1}}
}
schema = {"oneOf": [branch("invoice", "invoice_number"),
branch("receipt", "receipt_number")]}
v = Draft202012Validator(schema)
valid = lambda x: not list(v.iter_errors(x))
assert valid({"kind": "invoice", "invoice_number": "I-1"})
assert valid({"kind": "receipt", "receipt_number": "R-1"})
assert not valid({"kind": "invoice", "receipt_number": "R-1"})
assert not valid({"kind": "receipt", "receipt_number": ""})
assert not valid({"kind": "invoice", "invoice_number": "I-1",
"receipt_number": "R-1"})
assert not valid({"kind": "unknown"})
Đây là một bản ghi ví dụ được đơn giản hóa, không phải mô hình hoàn chỉnh của một hóa đơn thực tế. Mã cho thấy việc lựa chọn và từ chối các trường trùng lặp ở chi nhánh; mức thuế, tiêu đề và số tiền cần được định nghĩa riêng biệt.
Nếu doanh nghiệp cho phép các trường bổ sung, các không gian tên cho các trường này nên được xác định rõ ràng thay vì âm thầm loại bỏ tất cả các ràng buộc.
Đừng chỉ hiển thị thông báo lỗi "không khớp"
Chỉ hiển thị "không khớp", và cả người dùng lẫn nhân viên bảo trì đều không thể biết vấn đề nằm ở đâu. Bảng dưới đây liệt kê một số đặc điểm đầu vào phổ biến và các phương pháp phản hồi tương ứng của chúng:
| Tính năng đầu vào | Những nghi ngờ thực sự | Đề xuất phản hồi |
|---|---|---|
| loại thiếu hụt | Không thể chọn thỏa thuận | Vui lòng cung cấp loại tài liệu |
| Trường kiểu và số xung đột | Hai cấu trúc này được pha trộn | Hiển thị các trường xung đột và nguồn của chúng |
| Chuỗi rỗng được đánh số | Chìa khóa tồn tại nhưng không có giá trị | Nhìn lại khu vực đánh số |
| Loại không xác định | Thỏa thuận hiện tại không bao gồm điều này | Nhập hàng đợi độc lập để được phân loại |
Các loại không xác định cũng cần thoát
Nếu bộ phân loại không thể phân biệt hóa đơn và hóa đơn, trạng thái chưa xác định nên được giữ lại thay vì chọn ngẫu nhiên một nhánh để tạo ra "thành công."
Có ba cấp độ khác nhau ở đây cần được xem xét riêng biệt:
- Độ tin cậy danh mục: Độ tin cậy của hệ thống trong việc đánh giá các loại tài liệu.
- Xác minh cấu trúc: Nhập liệu hợp đồng đã chọn có được đáp ứng hay không.
- Tính xác thực kinh doanh: Liệu các tài liệu có chính xác và hợp lệ hay không.
Việc xác minh cấu trúc không thể được chứng minh ngược lại là chính xác, cũng như không thể chứng minh tài liệu là thật.
Loại tài liệu cũng nên được giữ nguyên trong quá trình dịch
Cùng một lĩnh vực có thể yêu cầu thuật ngữ khác nhau trong các tài liệu khác nhau. Khi sử dụng thuật ngữ OmniDoc và quy trình đánh giá song ngữ, việc cung cấp các loại tài liệu với danh sách giao giúp người đánh giá hiểu được ngữ cảnh của số lượng và số lượng.
Đừng để một đối tượng JSON rộng lớn xóa đi những khác biệt này.
📊 So sánh cốt lõi
| Phương pháp | Loại tài liệu có thể được xác định rõ ràng không? | Biểu hiện khi các nhánh chồng lên nhau | Xử lý các loại không xác định |
|---|---|---|---|
| Các đối tượng rộng với tất cả các trường đều tùy chọn | Thật khó để diễn tả những gì đã nhận được | Không áp dụng; không có ranh giới nhánh giữa các trường | Dễ dàng bị nuốt chửng bởi các mục tiêu rộng lớn và khó nhận ra |
| Hai hợp đồng độc lập + loại yêu cầu | Chọn rõ ràng bằng trường loại | Sử dụng const để cố định giá trị nhằm giảm chồng lấn | Rời khỏi trạng thái chưa biết và vào hàng đợi để được sắp xếp |
🎯 Phương pháp nào phù hợp với bạn?
Nếu bạn cần nhận cả hóa đơn và hóa đơn cùng lúc
Giữ hai hợp đồng riêng biệt và đặt kind làm trường bắt buộc.
Nếu các trường nhánh của bạn chồng lấn rộng rãi
Sửa kind với const trong mỗi nhánh để tránh đầu vào hợp lệ khớp nhiều nhánh cùng lúc.
Nếu hệ thống của bạn cho phép các trường bổ sung
Đầu tiên, làm rõ không gian tên của trường bổ sung, sau đó quyết định cách nới lỏng các ràng buộc.
Nếu bộ phân loại của bạn không đủ chắc chắn
Giữ trạng thái chưa xác định và gửi tài liệu vào hàng đợi để sắp xếp; không bắt buộc chọn nhánh.
❓ Câu hỏi thường gặp (FAQ)
1. Tại sao không dùng một đối tượng mà tất cả các trường đều là tùy chọn?
Một người bạn đời như vậy có thể giả vờ bất cứ điều gì, nhưng thật khó để biết chính xác họ nhận được gì.
2. Tại sao oneOf lại gây ra thất bại vào hợp lệ?
oneOf yêu cầu khớp chính xác một nhánh. Nếu cả hai nhánh đều vượt qua đồng thời, kiểm tra tổng thể sẽ thất bại. Tình huống này có khả năng xảy ra khi các trường nhánh chồng lấn rộng rãi.
3. Bạn nên chú ý điều gì khi cho phép các trường bổ sung?
Không gian tên cho trường bổ sung nên được xác định rõ ràng, thay vì âm thầm loại bỏ mọi ràng buộc.
4. Nếu bộ phân loại không thể xác định loại tài liệu thì sao?
Giữ trạng thái chưa biết và vào hàng đợi độc lập để được phân loại; không chọn ngẫu nhiên một nhánh để lắp ráp nhánh thành công.
5. Việc vượt qua xác minh cấu trúc có chứng minh tính xác thực của các tài liệu không?
Không. Độ tin cậy phân loại, xác minh cấu trúc và tính xác thực doanh nghiệp là ba cấp độ riêng biệt; xác minh cấu trúc không thể chứng minh tính xác thực của tài liệu.
📝 Tóm tắt
Khi đặt hóa đơn và biên lai vào cùng một mục, hãy giữ hai hợp đồng riêng biệt và chọn chúng bằng trường kind cần thiết, giúp loại tài liệu nhập trở nên rõ ràng. Xác minh nhánh, phản hồi lỗi và xuất loại không xác định cũng nên được thiết kế cùng nhau.
Trải nghiệm ngay: Tải lên tài liệu của bạn để bắt đầu dịch, giữ nguyên định dạng gốc


