2011-10-22 15 views
6

Jest to podobne do tego pytania C# Get schema information when validating xmlprzechwytywania informacji Schema podczas walidacji XDocument

jednak pracuję z XDocument do celów LINQ.

Czytam/parsuję zestaw plików CSV i konwertuję do XML, a następnie sprawdzam poprawność kodu XML względem schematu XSD.

Chciałbym uchwycić konkretne błędy związane z wartościami elementów, wygenerować bardziej przyjazny dla użytkownika komunikat i przekazać je użytkownikowi, aby dane wejściowe mogły zostać poprawione. Jedną z pozycji, które chciałbym uwzględnić w danych wyjściowych, są niektóre informacje o schemacie (takie jak zakres dopuszczalnych wartości dla typu liczbowego).

W moim obecnym podejściu (które jestem otwarty na zmianę), jestem w stanie uchwycić wszystko, czego potrzebuję, z wyjątkiem informacji o schemacie.

Próbowałem uzyskać dostęp do SourceSchemaObject w argumencie ValidationEventArgs procedury obsługi zdarzenia Walidacja, ale zawsze jest to wartość pusta. Próbowałem również GetSchemaInfo z XElement, który wydaje się być również zerowy.

Używam RegEx do identyfikowania konkretnych błędów sprawdzania poprawności, które chcę przechwycić, i przechwytywanie danych z XElement za pośrednictwem argumentu nadawcy obsługi zdarzenia sprawdzania poprawności. Myślałam przekształcania schematu do XDocument i chwytając co muszę poprzez LINQ, ale wydaje mi się, że nie powinno być lepszym rozwiązaniem

Oto moja obecna metoda sprawdzenia poprawności:

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 
} 

i oto moja metoda zwrotna:

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); 

    } 
} 

linia w mojej metody wywołania zwrotnego var message = FieldValidationMessage(element, args); tylko zastępczy i nie istnieje jeszcze Celem tej metody jest to, aby zrobić 3 rzeczy:

  1. zidentyfikować konkretne błędy sprawdzania poprawności za pomocą wyrażenia regularnego na args.Message (to już działa, ja testowałem wzorców, które mam zamiar korzystania)

  2. Grab wartości atrybutów z XDocument związanego z konkretnym Xelement który jest przyczyną błędu (takie jak numer wiersza i kolumny w oryginalnym pliku CSV)

  3. Chwyć informacje o schemacie, jeśli są dostępne, aby typy pól i ograniczenia mogły zostać dodane do komunikatu wyjściowego.

Odpowiedz

6

Dla każdego, kto czyta to pytanie w przyszłości, udało mi się rozwiązać mój problem, aczkolwiek w nieco inny sposób, niż pierwotnie proponowałem.

Pierwszy problem, który miałem, że SchemaInfo zarówno w metodzie ValidationEventArgs, jak i GetSchemaInfo XElement były zerowe. Rozwiązałem to w taki sam sposób, jak w pytaniu, które pierwotnie łączyłem ....

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 
} 

Wydaje się, że informacji Schema nie jest dodawany do XObject do momentu zwrotnego walidacji, więc jeśli próbujesz uzyskać do niego dostęp w środku zwrotnego walidacji, to będzie zerowy, ale jeśli uchwycić element, a następnie dostęp, jeśli po zakończeniu metody sprawdzania poprawności, nie będzie miała wartości NULL.

Jednak to otworzyło kolejny problem. Model obiektowy SchemaInfo nie jest dobrze udokumentowany i miałem problem z analizowaniem go, aby znaleźć to, czego potrzebowałem.

Znalazłem to question po tym, jak zadałem moje oryginalne pytanie. Przyjęta odpowiedź łączy się z naprawdę świetnym postem blog, który przerywa model obiektu SchemaInfo. Trochę pracy zajęło mi udoskonalenie kodu, aby pasował do moich celów, ale dobrze ilustruje to, jak uzyskać SchemaInfo dla dowolnego elementu XmlReader (który mogłem zmienić, aby działał z XObject).

Powiązane problemy