VB XML Cookbook, Recipe 5: The “Halloween” Problem (Doug Rothaus)

Published 08 May 08 09:47 AM

In the last two XML cookbook entries, we talked about the technique of using the ReplaceWith method to perform an identity transform. While this technique may meet your needs, it can introduce a problem in your code commonly referred to as the “Halloween” problem. Let’s take a look at what the problem is, and how to solve it. (For details on the “Halloween” problem and recommended solutions, see this topic in the documentation.)

The “Halloween” problem describes a scenario where you have a set of data that is updated in some fashion while enumerating through that data set. As a result, you can encounter a null reference exception, or worse, you can end up modifying the wrong data. For example, consider this snippet of code based on the previous two XML cookbook recipe posts: 

  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>&#32;

                    </div>

 

     email.ReplaceWith(emailHtml)

  End Sub

If you ran this code, you would encounter a null reference error as shown here:

Null Reference Exception

The reason for the error is that the For…Each loop is looping through the results of a query for <eMail> elements. During the first call to the TransformEmail function, the <eMail> element is replaced with HTML. As a result, the query references an XML element that no longer exists.

How do you solve the problem then? There are a couple of solutions. The first is what you may have noticed in the previous cookbook entries: return the query results as a List using the ToList method. That is, the following code:

    For Each email In info...<act:eMail>

Is changed to…

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

Returning a List means that we’re no longer dealing with a query. Hence, an update that would affect the query, such as replacing an XML element with HTML, does not affect the List.

The other common solution to the “Halloween” problem is to write your code so that it does not modify the original document. Instead, you project your results into a new XML document. In the next cookbook post, we’ll look at an example of how to do this.

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# Airline Travel &raquo; VB XML Cookbook, Recipe 5: The ???Halloween??? Problem (Doug Rothaus) said on May 14, 2008 1:37 PM:

PingBack from http://www.travel-hilarity.com/airline_travel/?p=4528

# amarnath mishra said on November 26, 2009 10:04 PM:

I am facing the following problems, kindly tell me the solution as soon as possible.

the error is - "unexpected error number 70 has occurred: permission denied."

this error comes after clicking on to the "finish" while making the setup in visual basic 6.0 with windows xp

Leave a Comment

(required) 
(optional)
(required) 

  
Enter Code Here: Required

This Blog

Syndication

Page view tracker