2010-08-10 24 views
10

Tôi muốn kiểm tra (đúng hoặc sai) cho dù tệp XML tùy ý có khớp với một lược đồ đã cho hay không.Sử dụng .NET để xác nhận hợp lệ XML đối với lược đồ

Đối với những gì nó có giá trị, giản đồ là lược đồ Word 2003 WordML, mà Microsoft định nghĩa bằng cách sử dụng danh sách khoảng 7 *.xsd tệp.

Một trong những tập tin này cũng bao gồm các tập tin W3C xml.xsd, bằng cách bao gồm tuyên bố sau:

<xsd:import id="xml" namespace="http://www.w3.org/XML/1998/namespace" 
    schemaLocation="http://www.w3.org/2001/xml.xsd"></xsd:import> 

Tôi đang sử dụng mã NET như sau để làm xác nhận:

public static void validate(string filename) 
    { 
     XmlReaderSettings settings = new XmlReaderSettings(); 
     settings.Schemas.Add(
      "http://schemas.microsoft.com/office/word/2003/wordml", 
      //to get this file I downloaded "Office 2003: XML Reference Schemas", i.e. "Office2003XMLSchema.exe" 
      @"C:\Program Files\Microsoft Office 2003 Developer Resources\Microsoft Office 2003 XML Reference Schemas\WordprocessingML Schemas\wordnet.xsd" 
      ); 
     settings.ValidationType = ValidationType.Schema; 
     settings.ValidationEventHandler += new ValidationEventHandler(validationEventHandler); 
     XmlReader xmlReader = XmlReader.Create(filename, settings); 
     while (xmlReader.Read()) { } 
    } 

My vấn đề là nếu tôi chạy mã này trên một máy mà không được kết nối với internet, sau đó tôi nhận được một lỗi XmlSchemaValidationException đến hiệu quả mà nó không thể tìm thấy xml.xsd.

Để khắc phục điều này, tôi đã tải xuống bản sao xml.xsd và thêm nó một cách rõ ràng bằng phương pháp settings.Schemas.Add: xác thực hiện hoạt động chính xác khi máy không được kết nối với internet.

Tuy nhiên, khi máy được kết nối với Internet, bây giờ tôi gặp lỗi khi nói rằng The global attribute 'http://www.w3.org/XML/1998/namespace:lang' has already been declared.. Vì vậy, rõ ràng tôi hoặc cần phải thêm nó một cách rõ ràng, hoặc tôi không, tùy thuộc vào việc máy có thể âm thầm tải nó từ internet (hoặc thậm chí có lẽ trước đây đã có thể tải về nó, và có nó được lưu trữ trong bộ nhớ cache). một vài nơi).

Vì vậy, đó là "damned nếu tôi làm và damned nếu tôi không". Tôi có cần phải thử nó một cách, bắt được ngoại lệ và sau đó thử nó theo cách khác? Hoặc là có một giải pháp thanh lịch hơn?

Trả lời

4

Chúng tôi không thể thấy mã của bạn, nhưng Trong nhiều triển khai, điều này được xử lý bằng cách chuyển hướng yêu cầu cho tệp .xsd tới bản sao cục bộ bằng trình phân giải danh mục. Có một tài sản XmlReaderSettings.XmlResolver có thể được sử dụng cho việc này. Xem XMLCatalog.net để thực hiện được cấp phép Apache mà bạn có thể sử dụng.

Tác dụng phụ của việc này là bạn có thể lưu tất cả các lược đồ được lưu vào bộ nhớ cache cục bộ. Điều này đặc biệt quan trọng vì W3C sẽ chặn đọc quá nhiều vào trang web của họ và mã ngẫu nhiên của bạn (hoặc tệ hơn, mã của khách hàng của bạn) sẽ bắt đầu thất bại.

+0

Cảm ơn bạn đã đề xuất; Tôi sẽ thử nghiệm để xem liệu tôi có thể sửa chữa nó bằng cách sử dụng một lớp con 'System.Xml.XmlResolver'. – ChrisW

+1

Tôi hiện đã hoạt động. Tôi đã thất bại trước đây, bởi vì tôi đã được gán cho thuộc tính 'XmlReaderSettings.XmlResolver'; nhưng khi/bởi vì tôi đang sử dụng 'settings.Schemas.Add', do đó tôi cần thay vào đó để gán cho thuộc tính' settings.Schemas.XmlResolver'. – ChrisW

+1

@ChrisW: Tôi cũng nhận được lỗi "Thuộc tính chung" http://www.w3.org/XML/1998/namespace:lang 'đã được khai báo. ", Với mã tương tự như trong câu hỏi ban đầu của bạn. Bạn đã thiết lập các thiết lập.Schemas.XmlResolver cho XMLCatalogResolver hay cái gì khác? Tôi đã thử mà không có may mắn. Bất kỳ cơ hội nào bạn có thể dán mã làm việc của mình? – Jeremy