2011-10-22 40 views
6

Điều này tương tự như câu hỏi này C# Get schema information when validating xmlChụp thông tin lược đồ khi xác thực XDocument

Tuy nhiên, tôi đang làm việc với XDocument cho mục đích LINQ.

Tôi đang đọc/phân tích cú pháp tập hợp các tệp CSV và chuyển đổi thành XML, sau đó xác thực XML dựa trên lược đồ XSD.

Tôi muốn nắm bắt các lỗi cụ thể liên quan đến giá trị phần tử, tạo thêm thông điệp thân thiện với người dùng và cung cấp lại cho người dùng để dữ liệu đầu vào có thể được sửa. Một trong những mục tôi muốn đưa vào dữ liệu đầu ra là một số thông tin lược đồ (chẳng hạn như phạm vi giá trị chấp nhận được cho một kiểu số).

Trong cách tiếp cận hiện tại của tôi (mà tôi đang mở để thay đổi), tôi có thể nắm bắt mọi thứ tôi cần ngoại trừ thông tin lược đồ.

Tôi đã thử truy cập vào số SourceSchemaObject trong đối số ValidationEventArgs của trình xử lý sự kiện Validation, nhưng điều đó luôn luôn là rỗng. Tôi cũng đã thử các GetSchemaInfo của XElement và dường như cũng null.

Tôi đang sử dụng RegEx để xác định các lỗi xác thực cụ thể mà tôi muốn nắm bắt và lấy dữ liệu từ XElement thông qua đối số người gửi của trình xử lý sự kiện xác thực. Tôi đã nghĩ đến việc chuyển đổi schema để một XDocument và grabbing những gì tôi cần thông qua LINQ, nhưng có vẻ như với tôi rằng có phải là một lựa chọn tốt hơn

Dưới đây là hiện Validate Phương pháp của tôi:

private List<String> this.validationWarnings; 
private XDocument xDoc; 
private XmlSchemaSet schemas = new XmlSchemaSet(); 

public List<String> Validate() 
{ 
    this.validationWarnings = new List<String>(); 

    // the schema is read elsewhere and added to the schema set 
    this.xDoc.Validate(this.schemas, new ValidationEventHandler(ValidationCallBack), true); 

    return validationWarnings 
} 

và đây là phương pháp gọi lại tôi:

private void ValidationCallBack(object sender, ValidationEventArgs args) 
{   
    var element = sender as XElement; 

    if (element != null) 
    { 

     // this is a just a placeholder method where I will be able to extract the 
     // schema information and put together a user friendly message for specific 
     // validation errors  
     var message = FieldValidationMessage(element, args); 

     // if message is null, then the error is not one one I wish to capture for 
     // the user and is related to an invalid XML structure (such as missing 
     // elements or incorrect order). Therefore throw an exception 
     if (message == null) 
      throw new InvalidXmlFileStructureException(args.Message, args.Exception); 
     else 
      validationWarnings.Add(message); 

    } 
} 

dòng var message = FieldValidationMessage(element, args); trong phương pháp gọi lại tôi chỉ là một giữ chỗ và chưa hề tồn tại Mục đích của phương pháp này là để làm 3 điều:

  1. Xác định lỗi xác nhận cụ thể bằng cách sử dụng RegEx trên args.Message (điều này đã làm việc, tôi đã thử nghiệm mô hình mà tôi có kế hoạch sử dụng)

  2. Grab giá trị thuộc tính từ XDocument liên quan đến XElement cụ thể mà gây ra lỗi (chẳng hạn như số hàng và cột trong CSV gốc)

  3. Lấy thông tin lược đồ nếu có sẵn để loại trường và hạn chế có thể được thêm vào thông báo đầu ra.

Trả lời

6

Đối với bất kỳ ai đọc câu hỏi này trong tương lai, tôi đã giải quyết được vấn đề của mình, mặc dù theo một cách hơi khác so với tôi đề xuất ban đầu.

Vấn đề đầu tiên tôi gặp phải, rằng SchemaInfo cả trong ValidationEventArgs và phương thức mở rộng GetSchemaInfo của XElement là null. Tôi đã giải quyết nó theo cách tương tự như trong câu hỏi tôi đã liên kết ban đầu ....

List<XElement> errorElements = new List<XElement>(); 

serializedObject.Validate((sender, args) => 
{ 
    var exception = (args.Exception as XmlSchemaValidationException); 

    if (exception != null) 
    { 
     var element = (exception.SourceObject as XElement); 

     if (element != null) 
      errorElements.Add(element); 
    } 

}); 

foreach (var element in errorElements) 
{ 
    var si = element.GetSchemaInfo(); 

    // do something with SchemaInfo 
} 

Nó sẽ xuất hiện các thông tin Schema không được thêm vào các XObject cho đến sau khi gọi lại xác nhận, vì vậy nếu bạn cố gắng truy cập vào nó ở giữa gọi lại xác nhận, nó sẽ được null, nhưng nếu bạn chụp phần tử, sau đó truy cập nếu sau khi phương thức Validate hoàn thành, nó sẽ không rỗng.

Tuy nhiên, điều này đã mở ra một vấn đề khác. Mô hình đối tượng SchemaInfo không được tài liệu hóa tốt và tôi đã gặp khó khăn khi phân tích cú pháp nó để tìm ra những gì tôi cần.

Tôi đã tìm thấy số này question sau khi tôi hỏi câu hỏi ban đầu của mình. Câu trả lời được chấp nhận liên kết đến một bài đăng thực sự tuyệt vời blog phá vỡ mô hình đối tượng SchemaInfo. Nó đã cho tôi một chút công việc để tinh chỉnh mã cho phù hợp với mục đích của tôi, nhưng nó là một công việc tốt để minh họa cách lấy SchemaInfo cho bất kỳ phần tử XmlReader nào (mà tôi đã có thể thay đổi để làm việc với XObject).

Các vấn đề liên quan