XmlDocument.NodeInserted сработал в XmlDocument.Validate () - PullRequest
0 голосов
/ 08 октября 2018

В настоящее время я пишу приложение для изменения и обработки определенных XML-документов.

В моем приложении есть стек для отмены / повтора изменений, а также ведется запись изменений в XML DOM на консоль отладки.При каждом изменении DOM приложение проверяет документ, поэтому пользователь напрямую получает отзыв о недействительных записях.

Моя проблема в том, что метод XmlDocument.Validate () запускает действие XmlDocument.NodeInserted.Это приводит к бесконечному циклу обратного вызова.Как я могу предотвратить это поведение?

Части моего кода:
Инициализация / загрузка документа:

private void ParseStyleSheet(FileInfo stylesFile)
    {
        // load document
        XmlDocument document = new XmlDocument();
        document.PreserveWhitespace = true;
        document.Schemas = StyleSchemaSet.GetSchemaset();
        document.Load(stylesFile.FullName);
        // add event handlers
        document.NodeChanged += XmlNodeChangedAction;
        document.NodeChanged += _undoMngr.XmlNodeChangedEventHandler;
        document.NodeInserted += XmlNodeChangedAction;
        document.NodeInserted += _undoMngr.XmlNodeChangedEventHandler;
        document.NodeRemoved += XmlNodeChangedAction;
        document.NodeRemoved += _undoMngr.XmlNodeChangedEventHandler;
        // set namespace
        XmlNamespaceManager nameSpaceMngr = new 
        XmlNamespaceManager(document.NameTable);
        ...
}

Изменение обработчика / обратного вызова проверки:

    private void XmlNodeChangedAction(object src, XmlNodeChangedEventArgs args)
    {
        // debug outputs
        Debug.WriteLine("XML node is changing");
        Debug.Indent();
        Debug.WriteLine(args.Action);
        Debug.WriteLine("Old: " + args.OldValue);
        Debug.WriteLine("New: " + args.NewValue);
        _document.Validate(this.ValidationEventCallBack);//TODO leads to loop
        // undindent debug
        Debug.Unindent();
    }


    private void ValidationEventCallBack(object sender, ValidationEventArgs args)
    {
        switch (args.Severity)
        {
            case XmlSeverityType.Error:
                //TODO maybe throw for GUI message?
                Debug.WriteLine("XSD Error: " + args.Message);
                break;

            case XmlSeverityType.Warning:
                Debug.WriteLine("XSD Warning: " + args.Message);
                break;

            default:
                break;
        }
    }

Как только я меняю узел, я получаю бесконечный цикл изменений, который также отображается в консоли отладчика:

XML node is changing
Change
Old: 20px
New: 25px
XML node is changing
    Insert
    Old: #ebebeb
    New: #ebebeb
    XML node is changing
        Insert
        Old: #ebebeb
        New: #ebebeb
        XML node is changing
            Insert
            Old: #ebebeb
            New: #ebebeb
            XML node is changing
                Insert
                ...




Обновление (благодаря подсказке Дао):
Если документ уже проверен непосредственно после загрузки и перед добавлением делегата NodeInserted, цикл больше не выполняется.Таким образом, все изменения DOM уже произошли из-за первой проверки.

private void ParseStyleSheet(FileInfo stylesFile)
    {
        // load document
        XmlDocument document = new XmlDocument();
        document.PreserveWhitespace = true;
        document.Schemas = StyleSchemaSet.GetSchemaset();
        document.Load(stylesFile.FullName);
        document.Validate(ValidationEventCallBack);
        // add event handlers
        document.NodeChanged += XmlNodeChangedAction;
        document.NodeChanged += _undoMngr.XmlNodeChangedEventHandler;
        document.NodeInserted += XmlNodeChangedAction;
        document.NodeInserted += _undoMngr.XmlNodeChangedEventHandler;
        document.NodeRemoved += XmlNodeChangedAction;
        document.NodeRemoved += _undoMngr.XmlNodeChangedEventHandler;
        ...
    }

1 Ответ

0 голосов
/ 08 октября 2018

Документация для Validate () гласит:

Метод Validate выполняет расширение набора данных.В частности, после успешной проверки применяются значения по умолчанию схемы, текстовые значения при необходимости преобразуются в атомарные значения, а информация о типе связывается с проверенными информационными элементами.Результатом является ранее нетипизированное поддерево XML в XmlDocument, замененное типизированным поддеревом.

Мне кажется, что вам нужно добавить дополнительное состояние, чтобы отслеживать, является ли изменение«преднамеренный», или результат «расширения набора», которое происходит во время проверки.Что-то вроде отслеживания состояния «IsValidating» и исключения вызова _document.Validate () в этом состоянии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...