1

I am using XML reader to search through an xml configuration file we use. I want to find the values under a certain key and be able to change them or add if they don't exist.

XML Sample

<DBSimulatorConfigurations>
  <Configurations>
    <DBSimulatorConfiguration>
      <Key>Test1</Key>
      <Submit>0</Submit>
      <Amend>0</Amend>
      <Update>0</Update>
      <Delete>1</Delete>
    <ResponseTimeInSeconds>100</ResponseTimeInSeconds>
    </DBSimulatorConfiguration>
    <DBSimulatorConfiguration>
      <Key>Test2</Key>
      <Submit>0</Submit>
      <AutoUpdate>0</AutoUpdate>
      <Amend>0</Amend>
      <Update>0</Update>
      <Delete>1</Delete>
    <ResponseTimeInSeconds>100</ResponseTimeInSeconds>
    </DBSimulatorConfiguration>
    <DBSimulatorConfiguration>
  </Configurations> 
</DBSimulatorConfigurations>

Code so far... commented out bit doesn't find the value within 'Test1'

XmlReader reader = XmlReader.Create("C:\\<path>\\DBConfigs.xml");
while(reader.Read())
{
    if (reader.ReadToDescendant("Key"))
    {
        reader.Read();
        if (reader.Value == "Test1")
        {
            Console.WriteLine("Found_1 {0}", reader.Value);
            // Doesn't work :( 
            // reader.Read();
            //if (reader.ReadToDescendant("Submit")) {
            //  Console.WriteLine("Value for Submit is {0}", reader.Value);
            //}
        }

        if (reader.Value == "Test2")
        {
            Console.WriteLine("Found_2 {0}", reader.Value);
        }

        reader.Read(); //this moves reader to next node which is text 
        if (reader.ReadToDescendant("Full.2")) {
            Console.WriteLine("Found {0}", reader.Value);
        }

    }

But what I want to do then is find and change the value for 'Submit' or 'Amend' etc or if there is no entry 'Submit' then i'll add one.

But first i'd like to be able to find and change the values for Test1.

3

2 Answers 2

1

This appears to work to find value and update it. I've updated it so I can find any value for a particular value.

//search for  all nodes with <DBSimulatorConfiguration> element
string xml = "<path>.DBConfig.xml";
XDocument xdoc = XDocument.Load(xml);
var elements = xdoc.Root.Elements().Elements().Where(x => x.Name == "DBSimulatorConfiguration");
//iterate through all those eleemnt

foreach (var element in elements)
{
    //Console.WriteLine("Empty {0}", element.Value);
    //now find it's child named Submit
    var configKey = element.Elements().FirstOrDefault(x => x.Name == "Key");
    var configSubmit = element.Elements().FirstOrDefault(x => x.Name == "Submit");
    var configAmend = element.Elements().FirstOrDefault(x => x.Name == "Amend");
    var configUpdate = element.Elements().FirstOrDefault(x => x.Name == "Update");
    var configDelete = element.Elements().FirstOrDefault(x => x.Name == "Delete");

    //if such element is found
    if (configSubmit != null)
    {
        if (configKey.ElementsBeforeSelf().Any(x => x.Name == "Key" && x.Value == "Test1"))
        {
            Console.WriteLine("Found Key for Test1 {0}", configKey.Value);
        }
        if (configSubmit.ElementsBeforeSelf().Any(x => x.Name == "Key" && x.Value == "Test1"))
        {
            configSubmit.Value = "1";
            Console.WriteLine("Submit value is updated to {0}", configSubmit.Value);        
        }
        if (configAmend.ElementsBeforeSelf().Any(x => x.Name == "Key" && x.Value == "Test1"))
        {
            Console.WriteLine("Amend value is: {0}", configAmend.Value);
        }
        if (configUpdate.ElementsBeforeSelf().Any(x => x.Name == "Key" && x.Value == "Test1"))
        {
            Console.WriteLine("Update value is: {0}", configUpdate.Value);
        }
    }
}
xdoc.Save("<path>.DBConfig.xml");

Is this the most efficient way of doing this?

Sign up to request clarification or add additional context in comments.

Comments

0

Here is one approach, using XDocument:

 string xml = @"
<DBSimulatorConfigurations>
  <Configurations>
    <DBSimulatorConfiguration>
      <Key>Test1</Key>
      <Submit>0</Submit>
      <Amend>0</Amend>
      <Update>0</Update>
      <Delete>1</Delete>
    <ResponseTimeInSeconds>100</ResponseTimeInSeconds>
    </DBSimulatorConfiguration>
    <DBSimulatorConfiguration>
      <Key>Test2</Key>
      <Submit>0</Submit>
      <AutoUpdate>0</AutoUpdate>
      <Amend>0</Amend>
      <Update>0</Update>
      <Delete>1</Delete>
    <ResponseTimeInSeconds>100</ResponseTimeInSeconds>
    </DBSimulatorConfiguration>
    <DBSimulatorConfiguration>
    </DBSimulatorConfiguration>
  </Configurations> 
</DBSimulatorConfigurations>";

XDocument xdoc = XDocument.Parse(xml);
//search for  all nodes with <DBSimulatorConfiguration> element
var elements = xdoc.Root.Elements().Elements().Where(x => x.Name == "DBSimulatorConfiguration");
//iterate through all those eleemnt
foreach (var element in elements)
{
    //now find it's child named Submit
    var submitElement = element.Elements().FirstOrDefault(x => x.Name == "Submit");
    //if such element is found
    if (submitElement != null)
    {
        //here you can change Submit element, like this:
        // submitElement.Value = "abc";
        //or you can check for something
        if (submitElement.ElementsBeforeSelf().Any(x=> x.Name == "Key" && x.Value== "Test2"))
        {
            //this is submitElement which is after element named Key with value Test2
            submitElement.Value = "some specific value";
        }
    }
    else
        element.Add(new XElement("Submit", 999));
}

5 Comments

I am getting an error with code. "System.Xml.XmlException: Data at the root level is invalid. Line 1, position 1." The first lines of the xml file are: <DBSimulatorConfigurations> <Template></Template> <Configurations><DBSimulatorConfiguration>
@john your xml is not valid. XDocument expects valid xml. In fact, xml sample you provided in question was not valid either, it was missing closing DBSimulatorConfigurations node which I added. Xml in my answer should be valid and you can test code with it. To check your xml, you can use some of online tools like this one or this one
Both tools you listed below say my xml is valid. But I solved the issue by using XDocument.Load instead of XDocument.Parse
@John well, did my answer help you?
yes, thank you it was about 90% what i was looking for. I've added my final solution, but i can't tick my own solution as an answer for another few hours. So i'll just tick your answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.