Làm cách nào tôi có thể tìm hai tệp XML?


75

Trên Linux, làm cách nào tôi có thể tạo khác biệt giữa hai tệp XML?

Lý tưởng nhất, tôi muốn có thể cấu hình nó thành một số thứ nghiêm ngặt hoặc nới lỏng một số thứ, như khoảng trắng hoặc thứ tự thuộc tính.

Tôi thường quan tâm rằng các tệp có chức năng giống nhau, nhưng khác về bản thân nó, sẽ gây khó chịu khi sử dụng, đặc biệt là nếu tệp XML không có nhiều ngắt dòng.

Ví dụ, những điều sau đây thực sự sẽ ổn với tôi:

<tag att1="one" att2="two">
  content
</tag>

<tag att2="two" att1="one">
  content
</tag>

Câu trả lời:


86

Một cách tiếp cận trước tiên là biến cả hai tệp XML thành XML Canonical và so sánh các kết quả bằng cách sử dụng diff. Ví dụ, xmllint có thể được sử dụng để chuẩn hóa XML.

$ xmllint --c14n one.xml > 1.xml
$ xmllint --c14n two.xml > 2.xml
$ diff 1.xml 2.xml

Hoặc như một lớp lót.

$ diff <(xmllint --c14n one.xml) <(xmllint --c14n two.xml)

1
Chưa bao giờ biết về chuyển đổi --c14n trong xmllint. Thật tiện dụng.
qedi

18
Bạn cũng có thể làm điều đó trong một dòngvimdiff <(xmllint --c14n one.xml) <(xmllint --c14n two.xml)
Nathan Villaescusa

và xmllint giao hàng với OS X
ClintM

10
Trong trường hợp không rõ ràng, c14n là tên viết tắt của chuẩn hóa .
Brandin

3
Tốt hơn là thực hiện một bước bổ sung trước khi định dạng khác của cả hai XML (xmllint --format). Bởi vì tôi đã nhận thấy rằng không có bước này khác biệt cho thấy nhiều sự khác biệt hơn mức cần thiết.
ka3ak

23

Câu trả lời của Jukka không phù hợp với tôi, nhưng nó đã chỉ ra XML Canonical. Cả --c14n cũng không --c14n11 sắp xếp các thuộc tính, nhưng tôi đã tìm thấy các --exc-c14n tắc đã loại các thuộc tính. --exc-c14n không được liệt kê trong trang man, nhưng được mô tả trên dòng lệnh là "định dạng chính tắc độc quyền của W3C".

$ xmllint --exc-c14n one.xml > 1.xml
$ xmllint --exc-c14n two.xml > 2.xml
$ diff 1.xml 2.xml

$ xmllint | grep c14
    --c14n : save in W3C canonical format v1.0 (with comments)
    --c14n11 : save in W3C canonical format v1.1 (with comments)
    --exc-c14n : save in W3C exclusive canonical format (with comments)

$ rpm -qf /usr/bin/xmllint
libxml2-2.7.6-14.el6.x86_64
libxml2-2.7.6-14.el6.i686

$ cat /etc/system-release
CentOS release 6.5 (Final)

Cảnh báo --exc-c14n loại bỏ tiêu đề xml trong khi --c14n trả trước tiêu đề xml nếu không có.


18

Đã thử sử dụng câu trả lời của @Jukka Matilainen nhưng gặp vấn đề với khoảng trắng (một trong các tệp là một lớp lót lớn). Sử dụng --formatgiúp bỏ qua sự khác biệt không gian trắng.

xmllint --format one.xml > 1.xml  
xmllint --format two.xml > 2.xml  
diff 1.xml 2.xml  

Lưu ý: Sử dụng vimdifflệnh để so sánh song song các xml.


Trong trường hợp của tôi two.xmlđã được tạo ra one.xmlbởi một kịch bản. Vì vậy, tôi chỉ cần kiểm tra những gì đã được thêm / xóa bởi kịch bản.
Giáo sư

1
Đây là lựa chọn tôi cần. Giả sử phiên bản chính tắc nhất có thể thu được bằng cách kết hợp --formatvới --exc-c14n; có lẽ sẽ vẫn chậm hơn để xử lý :(
ᴠɪɴᴄᴇɴᴛ

Đã khá lâu kể từ khi tôi viết câu trả lời, nhưng tôi nhớ rất rõ khi sử dụng cờ --exc-c14n. Tuy nhiên, khác với đầu ra có / không có cờ cho thấy không có sự khác biệt nên chỉ dừng sử dụng nó. Bỏ cờ không cần thiết / không sử dụng có thể làm cho quá trình nhanh hơn.
Giáo sư

5
Các --exc-c14ntùy chọn định sắp xếp của các thuộc tính. Trong các tệp cụ thể của bạn, các thuộc tính có thể đã được sắp xếp, nhưng lời khuyên chung sẽ là sử dụng kết hợp --format --exc-c14n.
22/12/14

6

Diffxml có chức năng cơ bản chính xác, mặc dù nó dường như không cung cấp nhiều tùy chọn cho cấu hình.

Chỉnh sửa: Project Diffxml đã được di chuyển sang GitHub từ năm 2013.


Nó chưa hoàn toàn ở đó, nhưng ít nhất nó có vẻ đầy hứa hẹn.
qedi

Mặc dù vậy, không hữu ích cho các tệp lớn, đã chết sau khi ăn 40 GB (RAM + SWAP) khi so sánh hai tệp ~ 20k mỗi dòng
Grzegorz

lưu ý rằng dự án dường như đã chết, với bản cập nhật cuối cùng vào năm 2013
Mateusz Konieczny

4

Nếu bạn cũng muốn bỏ qua thứ tự các phần tử con, tôi đã viết một công cụ python đơn giản cho cái này được gọi là xmldiffs:

So sánh hai tệp XML, bỏ qua thứ tự phần tử và thuộc tính.

Sử dụng: xmldiffs [OPTION] FILE1 FILE2

Bất kỳ tùy chọn bổ sung được chuyển đến difflệnh.

Nhận nó tại https://github.com/joh/xmldiffs


1

Tập lệnh Python của tôi xdiff.py để so sánh các tệp XML bỏ qua sự khác biệt về thứ tự khoảng trắng hoặc thứ tự thuộc tính (trái ngược với thứ tự phần tử).

Để so sánh hai tệp 1.xml2.xml, bạn sẽ chạy tập lệnh như sau:

xdiff.py 1.xml 2.xml

Trong ví dụ của OP, nó sẽ không tạo ra gì và trả về trạng thái thoát 0(không có sự khác biệt về cấu trúc hoặc văn bản).

Trong trường hợp 1.xml2.xmlkhác nhau về cấu trúc, nó bắt chước đầu ra hợp nhất của GNU diff và trả về trạng thái thoát 1. Có nhiều tùy chọn khác nhau để kiểm soát đầu ra, chẳng hạn như -axuất ra tất cả bối cảnh, -nđể xuất ra không có ngữ cảnh và -qđể triệt tiêu hoàn toàn đầu ra (trong khi vẫn trả về trạng thái thoát).


0

Tôi sử dụng Beyond So sánh để so sánh tất cả các loại tệp dựa trên văn bản. Họ sản xuất các phiên bản cho Windows và Linux.


1
So sánh văn bản đơn giản sẽ nói hai dòng khác nhau, trong khi OP muốn chúng được báo cáo là như nhau.
ChrisF

4
tức là về mặt kỹ thuật so sánh XML.
Chris W. Rea

1
Beyond So sánh thực sự hút cho điều này. Dường như không nhận thức được các yếu tố XML và chủ yếu chỉ so sánh văn bản.
Rob K

Beyond So sánh có một plugin XML nhưng tôi không bao giờ có thể cài đặt nó đúng cách, vì vậy ... Nyeah ... Tôi đã đến trang này và trở nên khôn ngoan hơn ...
Erk

-1

Bộ phân biệt thông minh SD của chúng tôi so sánh các tài liệu dựa trên cấu trúc trái ngược với bố cục thực tế.

Có một bộ phân biệt thông minh XML. Đối với XML, điều đó có nghĩa là khớp thứ tự các thẻ và nội dung. Cần lưu ý rằng chuỗi văn bản trong đoạn cụ thể mà bạn chỉ ra là khác nhau. Hiện tại nó không hiểu khái niệm XML về các thuộc tính thẻ cho biết liệu khoảng trắng có được chuẩn hóa so với đáng kể hay không.


1
Trong hồ sơ SO của bạn, bạn cung cấp thông tin đầy đủ về chủ lao động của bạn; Tôi cũng muốn từ chối trách nhiệm ngắn trong câu trả lời của bạn :) BTW, tôi đã cố tải xuống một bản đánh giá, nhưng mẫu yêu cầu là 'thông minh' (thông qua JS) đủ để vô hiệu hóa XML kết hợp với Bộ phân biệt thông minh (cũng là mẫu sau kết hợp với Python, mặc dù có thể theo trang sản phẩm SD)?
27/11/14

1
Ah. Cảm ơn đã nhắc nhở. Đây là một câu trả lời từ thời trước khi có chính sách SO rõ ràng về vấn đề này. Tôi đang sửa đổi câu trả lời để báo hiệu mối quan hệ trong câu trả lời tuân thủ chính sách SO.
Ira Baxter

Tôi sẽ kiểm tra trang tải xuống; không phải tất cả các sản phẩm sống của chúng tôi làm cho danh sách đó. Vâng, những điều này tồn tại.
Ira Baxter

Tôi đã kiểm tra trang tải xuống. Có, bộ phân biệt thông minh XML không có ở đó. Tôi sẽ có những người ở hậu trường sửa chữa điều đó; nên có mặt trong tối đa 1-2 tuần (họ có tồn đọng, không phải tất cả chúng ta sao?) Trong khi đó, nếu bạn muốn dùng thử, hãy gửi email (xem tiểu sử).
Ira Baxter

1
Trang được liên kết không có từ "XML" trong đó.
Mateusz Konieczny

-1

Không chắc chắn liệu (sự phụ thuộc của) một công cụ trực tuyến có được tính là một giải pháp hay không, nhưng với giá trị của nó, tôi đã có kết quả tốt trong công cụ so sánh XML trực tuyến này . Nó chỉ đơn giản là hoạt động.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.