VB XML手册5:”Halloween”问题

Categories: VB
Comments: No Comments
Published on: 2008 年 11 月 01 日

[原文作者]:Doug Rothaus

[原文链接]:VB XML Cookbook, Recipe 5: The “Halloween” Problem (Doug Rothaus)

    在前两次的手册中,我们讲了关于用ReplaceWith这个方法来进行身份转换.如果这个方法满足了你的需要,它会在你的代码中引发另外一个问题–"Halloween".让我们看看这个问题到底是怎样的,怎么样去解决.(详细的"Halloween"问题和解决方案可以参考这个文档).

    "Halloween"描述的场景是,你有一个以某种方式更新的数据集同时这个数据集又在被遍历的话,你会得到一个空引用的异常,更坏的是,你的代码可能会因为修改错误的数据而崩溃.例如前面两个手册用到的代码段:

Private Sub Recipe5(ByVal xmlPath As String)

    Dim xmlDoc = XDocument.Load(xmlPath)

 

    Dim info = xmlDoc.<Contacts>.<Contact>.<aci:AdditionalContactInfo>

 

    ‘ Replace e-mail address tags with mailto links.

    For Each email In info…<act:eMail>

      TransformEmail(email)

    Next

  End Sub

 

  Private Sub TransformEmail(ByVal email As XElement)

    Dim emailHtml = <div class="Email">

                      <a href=<%= "mailto:" & email.<act:eMailAddress>.Value %>>

                        <%= email.<act:eMailAddress>.Value %>

                      </a>

                    </div>

 

     email.ReplaceWith(emailHtml)

  End Sub

 

    如果你运行这段代码,就会得到下面的异常:

 

      这个异常的出现是因为For… Each循环正在循环用<eMail>元素查询出来的结果。在第一次调用TransformEmail个方法的时候,<eMail>这个元素已经被HTML替换掉了,结果,这个查询引用的就是已经不存在的XML元素了。

    要怎么解决这个问题呢?有几个解决方案,第一,你可能你已经注意到了在前面的手册中,把这个查询的结果用ToList方法返回一个List。像下面的代码

    For Each email In info…<act:eMail>

    改为:

    For Each email In info…<act:eMail>.ToList()

    返回一个List,表明要处理的就不再是一个查询结果,而更新就会作用到查询上面,例如用HTML替换XML,这样就不会影响到List。

    其他比较普遍的解决方案就是你的代码不要修改原本的文件,把结果放到新的XML文件中。下一个手册我会讲怎么做。

No Comments - Leave a comment

Leave a comment


Welcome , today is 星期一, 2017 年 03 月 27 日