Storing Values in XML & Using Linq to XML in VB to retrieve them
Here's a little background on the project I've been creating for the
past 2 weeks... Take uploaded XML files, do some file validation
against a database using Linq to SQL, and distribute these files across
our network based on the values within the XML file. Through all this,
wire in notifications if the file fails a validation test.
As
with any other application, there are many variables. In my case, I
was setting file directories, strings for email attributes, error
messages, etc. Setting these variables within the app was not only
'ugly code' to fight through, but any changes meant recompilation.
Most of these variables are going to need changed over time as business
changes, so why put myself through that???
Given the fact I was
already reading XML files using Linq to XML, it was decided to create
an XML file to hold all these values. It's definitely something that
can be easily edited with new values & placed directly into
production without causing any major issues.
Example XML (we'll call this settings.xml and will be saved in the root directory with the app):
<Settings>
<Notifications>
<Email>
<To>anyone@someone.com</To>
<From>someone@someone.com</From>
<Subject>{0} Email Notification</Subject>
<Body>This is the {0} email for the {1} task.</Body>
</Email>
</Notifications>
</Settings>
So now, let me tell you how easy Linq to XML in VB really is. To get the email subject & body, the code is as follows:
Dim _xml as XDocument = XDocument.Load("settings.xml")
Dim _subject = _xml...<Settings>.<Notifications>.<Email>.<Subject>.Value
Dim _subject = _xml...<Settings>.<Notifications>.<Email>.<Body>.Value
In
3 lines of code, I was able to set a _subject and _body variable to the
value in the XML file. This, of course, comes with an assumption that
the child nodes only appear once in your XML file. Notice I did not
strongly type the _subject and _body variables, this is called
anonymous types. If the nodes appear more than once, you will return
a collection object called _subject and _body, rather than a string for
each, that will need to be looped through with logic to find the value
you are searching. In my case, the XML file I'm using for these
settings was something I created, so I purposely made sure nodes were
not repeated to only return one value when searching through the XML.
Another
thing you may have noticed was the use of token {0} in the Subject and
{0} and {1} in the Body values. You can now use these email settings
for a range of different emails without creating different values using
String.Format().
Example:
Dim _subject = String.Format(_xml...<Settings>.<Notifications>.<Email>.<Subject>.Value, "Failure")
Dim
_body = String.Format(_xml...
<Settings>.<Notifications>.<Email>.<Body>.Value,
"failure", "assigned")
In this case, the token {0} is replaced
by "Failure" (without quotes), so now your _subject variable string
will read: Failure Email Notification. The _body variable has the
"failure" string and "assigned" string replacing tokens {0} and {1}
respectively. The _body variable string will now read: This is the
failure email for the assigned task.
As you can see, Linq to XML
saves a lot of time when getting values from an XML file. Use this to
your advantage, I'm definitely glad I did.
I started using
Generics today to hold a collection of emails as the application
processes The last step of the application is to iterate through the
generic list, using the variables I set from my XML file to send out
the emails. I'm still getting my hands around generics, but once I do,
it should make for a great blog post! Keep your eyes open in the next
few weeks for it!