首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >XmlDocument.NodeInserted在XmlDocument.Validate()上触发

XmlDocument.NodeInserted在XmlDocument.Validate()上触发
EN

Stack Overflow用户
提问于 2018-10-08 07:42:51
回答 1查看 64关注 0票数 0

我目前正在编写一个应用程序来修改和处理特定的XML文档。

我的应用程序有一个用于撤消/重做更改的堆栈,并且还将XML上的更改记录到Debug控制台。对于DOM的每一次更改,应用程序都会验证文档,因此用户直接获得无效条目的反馈。

我的问题是,XmlDocument.Validate()方法触发了一个XmlDocument.NodeInserted操作。这将导致一个没完没了的回调循环。我怎样才能防止这种行为?

我代码的一部分:

初始化/加载文档:

代码语言:javascript
复制
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);
        ...
}

更改处理程序/验证回调:

代码语言:javascript
复制
    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;
        }
    }

一旦我改变了一个节点,我就会得到一个无穷无尽的变化循环,这个循环也会显示在调试器控制台中:

代码语言:javascript
复制
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更改都已经发生了。

代码语言:javascript
复制
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;
        ...
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-10-08 07:51:33

验证()的文档说:

验证方法执行信息集增强。具体来说,在成功验证之后,将应用架构默认值,必要时将文本值转换为原子值,类型信息与已验证的信息项相关联。结果是XmlDocument中以前没有类型的XML子树被类型化子树所取代。

在我看来,您需要添加一些附加的状态来跟踪更改是“有意的”,还是验证过程中发生的“信息集增强”的结果。类似于跟踪"IsValidating“状态,并在处于该状态时避免调用_document.Validate()。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52697564

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档