Update an Existing Element Using Linq

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Edwin

    Update an Existing Element Using Linq

    I am trying to write an application among which one of the functions is to
    determine the number of unique extensions found in a directory and all of
    its sub directories. I am trying to use Linq to XML to do this.

    Below is the code being used to accomplish what I am trying to do. In the
    "if" statement, I am trying to update the <Count></CountElement to
    "TESTING". However what I will really want is to add 1 to the existing
    numerical value.

    Your help is greatly appreciated!


    System.IO.FileI nfo myCurrentFile;
    System.Xml.Linq .XElement myFileCountCurr entElement;

    var Extensions = new XElement("Count ", (from Extension in
    _myFileExtensio nCount.LinqXDoc ument.Descendan ts("Extension" ) where
    Extension.Eleme nt("Name").Valu e == myCurrentFile.E xtension.ToLowe r()
    select new
    {
    Name =
    Extension.Eleme nt("Name").Valu e,
    Count =
    Extension.Eleme nt("Count").Val ue,
    }));


    // An unaccounted file extension has been found. Let's add it.
    if (Extensions.IsE mpty == true)
    {
    myFileCountCurr entElement = _myFileExtensio nCount.LinqXDoc ument.Root;
    myFileCountCurr entElement =
    _myFileExtensio nCount.AppendXm lElement(myFile CountCurrentEle ment,
    "Extension" , null);
    _myFileExtensio nCount.AppendXm lElement(myFile CountCurrentEle ment,
    "Name", myCurrentFile.E xtension.ToLowe r());
    _myFileExtensio nCount.AppendXm lElement(myFile CountCurrentEle ment,
    "Count", "1");
    }
    else
    {
    Extensions.SetV alue("TESTING") ;
    }

    Below is the XML output that I am getting.


    <?xml version="1.0" encoding="utf-8" ?>
    - <FileExtensions >
    - <Extension>
    <Name>.m4b</Name>
    <Count>1</Count>
    </Extension>
    - <Extension>
    <Name>.docx</Name>
    <Count>1</Count>
    </Extension>
    - <Extension>
    <Name>.doc</Name>
    <Count>1</Count>
    </Extension>
    - <Extension>
    <Name>.xls</Name>
    <Count>1</Count>
    </Extension>
    - <Extension>
    <Name>.xlsx</Name>
    <Count>1</Count>
    </Extension>
    </FileExtensions>

  • Martin Honnen

    #2
    Re: Update an Existing Element Using Linq

    Edwin wrote:
    Below is the XML output that I am getting.
    >
    >
    <?xml version="1.0" encoding="utf-8" ?>
    - <FileExtensions >
    - <Extension>
    <Name>.m4b</Name>
    <Count>1</Count>
    </Extension>
    - <Extension>
    <Name>.docx</Name>
    <Count>1</Count>
    </Extension>
    - <Extension>
    <Name>.doc</Name>
    <Count>1</Count>
    </Extension>
    - <Extension>
    <Name>.xls</Name>
    <Count>1</Count>
    </Extension>
    - <Extension>
    <Name>.xlsx</Name>
    <Count>1</Count>
    </Extension>
    </FileExtensions>
    Here is an example that adds 1 to each Count element in the sample above:

    XDocument doc = XDocument.Parse (@"<FileExtensi ons>
    <Extension>
    <Name>.m4b</Name>
    <Count>1</Count>
    </Extension>
    <Extension>
    <Name>.docx</Name>
    <Count>1</Count>
    </Extension>
    <Extension>
    <Name>.doc</Name>
    <Count>1</Count>
    </Extension>
    <Extension>
    <Name>.xls</Name>
    <Count>1</Count>
    </Extension>
    <Extension>
    <Name>.xlsx</Name>
    <Count>1</Count>
    </Extension>
    </FileExtensions> ");
    foreach (XElement ext in doc.Root.Elemen ts("Extension") ) {
    ext.SetElementV alue("Count", (int)ext.Elemen t("Count")
    + 1);
    }
    doc.Save(Consol e.Out);

    HTH

    --

    Martin Honnen --- MVP XML

    Comment

    • Edwin

      #3
      Re: Update an Existing Element Using Linq

      I do not want to update every <Count></Countfor every extension. I just
      want to udpate the <Count></Countonly if the <Name></Nameapplies for the
      current extension being looked at.

      For example:

      <Extension>
      <Name>.m4b</Name>
      <Count>10</Count>
      </Extension>
      <Extension>
      <Name>.docx</Name>
      <Count>7</Count>
      </Extension>
      <Extension>
      <Name>.doc</Name>
      <Count>324</Count>
      </Extension>
      <Extension>
      <Name>.xls</Name>
      <Count>98</Count>
      </Extension>
      <Extension>
      <Name>.xlsx</Name>
      <Count>45</Count>
      </Extension>
      </FileExtensions>

      Comment

      • Martin Honnen

        #4
        Re: Update an Existing Element Using Linq

        Edwin wrote:
        I do not want to update every <Count></Countfor every extension. I
        just want to udpate the <Count></Countonly if the <Name></Name>
        applies for the current extension being looked at.
        Well my code was just meant as an example.
        Here is a different example that updates Count for one Extension element:

        XDocument doc = XDocument.Parse (@"<FileExtensi ons>
        <Extension>
        <Name>.m4b</Name>
        <Count>10</Count>
        </Extension>
        <Extension>
        <Name>.docx</Name>
        <Count>7</Count>
        </Extension>
        <Extension>
        <Name>.doc</Name>
        <Count>324</Count>
        </Extension>
        <Extension>
        <Name>.xls</Name>
        <Count>98</Count>
        </Extension>
        <Extension>
        <Name>.xlsx</Name>
        <Count>45</Count>
        </Extension>
        </FileExtensions> ");

        string exampleExt = ".docx";
        XElement extension = doc.Root.Elemen ts("Extension") .Where(e
        =e.Element("Nam e").Value == exampleExt).Fir stOrDefault();
        if (extension != null)
        {
        extension.SetEl ementValue("Cou nt", 1 +
        (int)extension. Element("Count" ));
        }
        doc.Save(Consol e.Out);


        --

        Martin Honnen --- MVP XML

        Comment

        • Edwin

          #5
          Re: Update an Existing Element Using Linq

          Excellent! It worked!

          I am not sure I understand it but it did exactly what I wanted it to do. I
          now have to learn what exactly is happening.

          Thanks for your help!

          Comment

          • Martin Honnen

            #6
            Re: Update an Existing Element Using Linq

            Edwin wrote:
            I am not sure I understand it but it did exactly what I wanted it to
            do. I now have to learn what exactly is happening.
            It is not that complicated, just uses LINQ to XML properties (like Root)
            and methods (like Elements("Exten sion")) and LINQ queries with a lambda
            expression:

            string exampleExt = ".docx";
            XElement extension = doc.Root.Elemen ts("Extension") .Where(e
            =e.Element("Nam e").Value == exampleExt).Fir stOrDefault();
            if (extension != null)
            {
            extension.SetEl ementValue("Cou nt", 1 +
            (int)extension. Element("Count" ));
            }

            So doc.Root accesses the root element, doc.Root.Elemen ts("Extension" )
            all "Extension" child elements of the Root. Then the LINQ Where method
            filters those elements with the lambda expression
            e =e.Element("Nam e").Value == exampleExt
            meaning it takes those "Extension" elements which have a "Name" child
            element where the Value is equal to exampleExt.

            FirstOrDefault( ) simply means we want only the first of those filtered
            elements or null if there is noone.

            Once we have found an element all we need to do is set the value of the
            "Count" child element using SetElementValue by incrementing the value by
            one, to do that we can cast the "Count" child element to an int and add
            1. That cast works as XElement provides

            to cast do a lot of CLR types.

            --

            Martin Honnen --- MVP XML

            Comment

            Working...