0

I need to modify the CompValue from "C02" to "C02,C03" . How to achieve this ?I have tried various ways to modify the XML content but so far could not find a solution.

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml("XML value");

XmlNode root = xmlDoc.DocumentElement;
XmlNode myNode = root.SelectSingleNode("descendant::CompValue");
myNode.Value = "blabla";

Also

root.SelectSingleNode("//CritGroup/Crit").InnerText = "NewValue";

This is my sample xml

<Search Name="Test1" ProjTypeID="107">
    <SearchType SearchTypeID="20246" />
    <FiscalYear Year="2022" />
    <CorpEnt CEID="367" CEName="Sample" />
    <CritGroup CritGroupID="1" CritGroupAndOr="AND">
        <Crit CritID="205" RelID="275" CompValue="C02" CompValueHuman="C02" AndOr="AND" TextBoxName="tbProjNum" /> 
        <Crit CritID="208" RelID="280" CompValue="11" CompValueHuman="Yes" AndOr="AND" TextBoxName="" />
    </CritGroup>
    <PageSize Size="200" />
</Search>
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Sribin
  • 307
  • 4
  • 16
  • 1
    Use an XDocument instead of an XmlDocument: https://stackoverflow.com/questions/16221558/how-to-get-value-of-child-node-from-xdocument – GH DevOps Jul 17 '23 at 13:53
  • @GHDevOps I thought `System.Xml.Linq` was for _read-only_ XML navigation. – Dai Jul 17 '23 at 14:13
  • @Dai, **LINQ to XML** API (circa 2007 nd later) is a "replacement" of the original .Net Framework XML API (circa 2002 - 2006). – Yitzhak Khabinsky Jul 17 '23 at 14:35
  • Does this answer your question? [How to change XML node values](https://stackoverflow.com/questions/11903552/how-to-change-xml-node-values) – Heretic Monkey Jul 17 '23 at 14:36
  • @YitzhakKhabinsky It isn't functionallity equivalent: Linq-to-Xml is designed around _replacing_ elements to make changes instead of mutating them in-place - e.g. you can't overwrite a substring of `innerText`, for example: https://learn.microsoft.com/en-us/dotnet/standard/linq/modify-elements-attributes-nodes-xml-tree – Dai Jul 17 '23 at 14:37
  • @Dai, it is not just functionality replacement, it does much more. – Yitzhak Khabinsky Jul 17 '23 at 14:39
  • @YitzhakKhabinsky `System.Xml.Linq` is all _in-memory_ - whereas if you want to _stream_ XML data or have high-performance forward-only reading then you have to use `System.Xml`. I think you drank the Linq kool-aid there. – Dai Jul 17 '23 at 14:47

2 Answers2

2

Please try the following solution.

It is using LINQ to XML API that is available in the .Net Framework since 2007.

c#

void Main()
{
    XDocument xdoc = XDocument.Parse(@"<Search Name='Test1' ProjTypeID='107'>
            <SearchType SearchTypeID='20246'/>
            <FiscalYear Year='2022'/>
            <CorpEnt CEID='367' CEName='Sample'/>
            <CritGroup CritGroupID='1' CritGroupAndOr='AND'>
                <Crit CritID='205' RelID='275' CompValue='C02' CompValueHuman='C02'
                      AndOr='AND' TextBoxName='tbProjNum'/>
                <Crit CritID='208' RelID='280' CompValue='11' CompValueHuman='Yes'
                      AndOr='AND' TextBoxName=''/>
            </CritGroup>
            <PageSize Size='200'/>
        </Search>");

    var Crits = xdoc.Descendants("Crit")
        .Where(x => x.Attribute("CompValue").Value == "C02");
    
    foreach (XElement Crit in Crits)
    {
        Crit.Attribute("CompValue").SetValue("C02,C03");
    }
}

Output XML

<Search Name="Test1" ProjTypeID="107">
  <SearchType SearchTypeID="20246" />
  <FiscalYear Year="2022" />
  <CorpEnt CEID="367" CEName="Sample" />
  <CritGroup CritGroupID="1" CritGroupAndOr="AND">
    <Crit CritID="205" RelID="275" CompValue="C02,C03" CompValueHuman="C02" AndOr="AND" TextBoxName="tbProjNum" />
    <Crit CritID="208" RelID="280" CompValue="11" CompValueHuman="Yes" AndOr="AND" TextBoxName="" />
  </CritGroup>
  <PageSize Size="200" />
</Search>
Yitzhak Khabinsky
  • 18,471
  • 2
  • 15
  • 21
1

You need to get the complete node and replace the attribute. Here is the example

    var xmlDoc = new XmlDocument();
    xmlDoc.LoadXml(xml);

    var critNode = xmlDoc.SelectSingleNode("//Crit[@CompValue='C02']");

    if (critNode != null)
    {
        var compValueAttr = critNode.Attributes["CompValue"];
        if (compValueAttr != null)
        {
            compValueAttr.Value = "C02,C03";
        }
    }

    var modifiedXml = xmlDoc.OuterXml;
    Console.WriteLine(modifiedXml);
Krishna Varma
  • 4,238
  • 2
  • 10
  • 25