Quickly Changing Values of XML Elements Using LINQ

Quickly Changing Values of XML Elements Using LINQ

  • Comments 10

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!
Leave a Comment
  • Please add 3 and 6 and type the answer here:
  • Post
  • Sharepoint SharePoint as a WCF Host [Via: Sahil Malik ] SharePoint 2007 as a WCF host - Step #4, Write...

  • Great article, Beth.  Productivity is skyrocketing with Linq. :)

    Is it possible to do stuff like querying an entire element (along with all of its children, grandchildren etc) and inserting that element into another XML document? (without looping through the entire hierarchy)

  • This is fine.

    But why Visual Studio change my Linq xml like (fragment)

    <!                <- space />

    <SomeText> </SomeText>

    to

    <SomeText></SomeText>

    and not preserve my spaces.

    It isn't good testing for such helpful product. Wait for sp1 8-).

  • Can code like this be run from a web page?  We have an ASP page the hits an Access db and the ISP keeps messing up the Access file.  Would something like this simplify our file problem?

    Thanks, Fred

  • Beth,

    Which Imports should I set so that the following code works? If possible send reply(ies) to my twitter account at @guerchele. Thanks in advance.

    'Each one? Both?

    'Imports <xmlns:p="urn:mycompany:examples:plants">

    'Imports <xmlns:p="urn:mycompany:examples:people">

    Module Module1

       Sub Main()

           Dim plants = <?xml version="1.0" encoding="ISO-8859-1"?>

                        <CATALOG xmlns:p="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 people = <?xml version="1.0" encoding="ISO-8859-1"?>

                        <CATALOG xmlns:p="urn:mycompany:examples:people">

                            <PERSON>

                                <NAME>blah blah blah</COMMON>

                            </PERSON>

                            <PERSON>

                                <NAME>blah blah blah</COMMON>

                            </PERSON>

                            <PERSON>

                                <NAME>blah blah blah</COMMON>

                            </PERSON>

                        </CATALOG>

           plants.Save("plants.xml")

           people.Save("people.xml")

       End Sub

    End Module

  • Hi Beth,

    This is exactly what I was looking for.  I watched some more of your videos and I found the one with xml tool.  I assume it is the video you reference in this article.  Now, when I am parsing xml, I get the entire typeahead feature.  It's really a boon.

    I had been working on Vista and VS2008 at home, to get ahead of the curve at work.  From describing my findings, I was able to get both approved at work.

    The LINQ alone is going to make my life so much easier!  We are on this push to make all our applications configurable via xml config files.  This specification is so much easier met when I have tools like LINQ, I am one happy camper.

    Thanks again, You're the best!

    John.

  • Lucian and others, to get this working add the following import:

    Imports &lt;xmlns="urn:mycompany:examples:plants"&gt;

  • Lucian and others, to get this working add the following import:

    Imports <xmlns="urn:mycompany:examples:plants">

  • [原文作者]: Beth Massi [原文链接]: Quickly Changing Values of XML Elements Using LINQ 最近我在考虑一些关于如何使用LINQ查询XML文档

  • Hi Beth,

    First of all, I like your "how do I" video series! I've seen many of them and are a great help! Now I'm trying to learn LINQ to XML and I've read and viewed most (if not all) of your posts and videos though I still have a problem and hope you can offer some advice.

    Let's say you want to create a diary and store each day in one xml file. After one year a new empty xml file will be created to reduce file size. How would I make this xml file containing data for a whole year searchable using LINQ?

    example:

    <day>

     <Date>28/03/2009</Date>

     <Wheather>Rainy</Wheather>

     <Where_was_I>At home</Where_was_I>

     <Story_morning>some text here what i was doing in the morning on this particular day</Story_morning>

     <Story_afternoon>some text here what i was doing in the afternoon on this particular day</Story_afternoon>

     <Story_evening>some text here what i was doing in the evening on this particular day</Story_evening>

     <Had_to_work>False</Had_to_work>

     <Friends_met>Erik, Eline, Alex</Friends_met>

    </Day>

    My question:

    How would my LINQ querie look if I want to search the story field "<Story_evening>" for a specific searchstring like "party" (contains the word) in a specific date range (between two dates).

    I supose this might result in a fairly big request for you to answer it but any help would be appreciated.

    Obviously one would probably use a database instead but I cannot use databes for this purpose since I don't have SQL server at my disposal.

    Thank you very much (for your video series and maybe for your help on this ;))

    Vincent

    ps

    Sorry for my spelling my english is a bit 'rusty'

Page 1 of 1 (10 items)