Quickly Changing Values of XML Elements Using LINQ
I've had many questions lately on how you can query for a specific node in an XML document (or fragment) and change it's value using LINQ. (This must mean that people are really starting to use this stuff so I'm pretty excited.) This is really easy to do because you can modify the values of the selected XElements from your queries and that will change the source XML.
Here's an example:
Imports <xmlns="urn:mycompany:examples:plants">
Module Module1
Sub Main()
Dim plants = <?xml version="1.0" encoding="ISO-8859-1"?>
<CATALOG xmlns="urn:mycompany:examples:plants">
<PLANT>
<COMMON>Bloodroot</COMMON>
<BOTANICAL>Sanguinaria canadensis</BOTANICAL>
<ZONE>4</ZONE>
<LIGHT>Mostly Shady</LIGHT>
<PRICE>$2.44</PRICE>
<AVAILABILITY>031599</AVAILABILITY>
</PLANT>
<PLANT>
<COMMON>Columbine</COMMON>
<BOTANICAL>Aquilegia canadensis</BOTANICAL>
<ZONE>3</ZONE>
<LIGHT>Mostly Shady</LIGHT>
<PRICE>$9.37</PRICE>
<AVAILABILITY>030699</AVAILABILITY>
</PLANT>
<PLANT>
<COMMON>Marsh Marigold</COMMON>
<BOTANICAL>Caltha palustris</BOTANICAL>
<ZONE>4</ZONE>
<LIGHT>Mostly Sunny</LIGHT>
<PRICE>$6.81</PRICE>
<AVAILABILITY>051799</AVAILABILITY>
</PLANT>
</CATALOG>
Dim q = From plant In plants...<PLANT> _
Where plant.<COMMON>.Value = "Columbine" _
Select plant
For Each item In q
q.<PRICE>.Value = "$49.99"
q.<LIGHT>.Value = "Full Sun"
Next
plants.Save("plants.xml")
End Sub
End Module
Couple things to note above, remember to import any namespaces being used in the XML otherwise your query will yield no results. And remember you can get XML IntelliSense if you import a schema (this is really easy, watch this). Of course, you can load the XML from a file (or URI) instead of using a literal and and get the same results.
Dim plants = XDocument.Load("plants.xml")
Dim q = From plant In plants...<PLANT> _
Where plant.<COMMON>.Value = "Columbine" _
Select plant
For Each item In q
q.<PRICE>.Value = "$49.99"
q.<LIGHT>.Value = "Full Sun"
Next
plants.Save("plants.xml")
In this example we're overwriting the source document, plants.xml, with our new values. Both examples produce this resulting XML:
<?xml version="1.0" encoding="iso-8859-1"?>
<CATALOG xmlns="urn:mycompany:examples:plants">
<PLANT>
<COMMON>Bloodroot</COMMON>
<BOTANICAL>Sanguinaria canadensis</BOTANICAL>
<ZONE>4</ZONE>
<LIGHT>Mostly Shady</LIGHT>
<PRICE>$2.44</PRICE>
<AVAILABILITY>031599</AVAILABILITY>
</PLANT>
<PLANT>
<COMMON>Columbine</COMMON>
<BOTANICAL>Aquilegia canadensis</BOTANICAL>
<ZONE>3</ZONE>
<LIGHT>Full Sun</LIGHT>
<PRICE>$49.99</PRICE>
<AVAILABILITY>030699</AVAILABILITY>
</PLANT>
<PLANT>
<COMMON>Marsh Marigold</COMMON>
<BOTANICAL>Caltha palustris</BOTANICAL>
<ZONE>4</ZONE>
<LIGHT>Mostly Sunny</LIGHT>
<PRICE>$6.81</PRICE>
<AVAILABILITY>051799</AVAILABILITY>
</PLANT>
</CATALOG>Enjoy!
Beth Massi is a Program Manager on the VS Community Team working with the Visual Basic Team producing developer content on MSDN and her blog (http://blogs.msdn.com/bethmassi). As a VB community champion and a member of the Microsoft community she helps run a .NET user group in the San Francisco Bay Area and is a frequent speaker at various software development events. Before Microsoft she was a Senior Systems Architect at a health care software product company and was a Microsoft Solutions Architect MVP. Over the last
decade she has worked on distributed applications and frameworks using Visual Basic.NET, ASP.NET, SQL-Server, and Visual FoxPro. She has worked on various projects including developing object-oriented middle-tier frameworks, COM, .NET, Web and Windows-based applications using Microsoft development tools for a variety of businesses. She loves teaching, mountain biking, and modifying cars.