0

Im using Visual studio 2019 and I would like to load, edit and save xml file.

xml file:

<?xml version="1.0" encoding="utf-8"?>
<Firstdelivery25 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.acm.nl/Operations/2018/09">
    <Firstdelivery>
        <MessageId xmlns="http://www.acm.nl/DataModel/2018/09">
            <Source>ABC</Source>
        </MessageId>
    </Firstdelivery>
</Firstdelivery25>

Code in Visual studio:

using System.Linq;
using System.Xml.Linq;
using System.Xml;
using TechTalk.SpecFlow;
XDocument xdoc = XDocument.Load(@"C:\\XML files\\25.xml");
            var element = xdoc.Elements("Source").FirstOrDefault();
            if (element != null)
            {
                element.Value = "DEF";
            }

            xdoc.Save(@"C:\\VB_25.xml");

When I execute this, the test is passed successfully. However, when I open the new created VB_25.xml file, the old value is still there.

Any help/suggestions/tips would be appreciated.

Vinni
  • 3
  • 2
  • The element Bron is null so nothing gets changed. – jdweng Dec 17 '20 at 13:32
  • The XML Element `Bron` doesn't exist, so nothing is changed. What you need is to get the `Firstdelivery25` then from it get the `Firstdelivery`, then the `MessageId` then the `source` and then change it's value. Or alternatively, you could create a C# class that represents this XML and deserialize it, change the value of a property and serialize it again – MindSwipe Dec 17 '20 at 13:32
  • My mistake. I have changed "xdoc.Elements("Bron")" to xdoc.Elements("Source"). I ran it again but the new file is still showing the old value. – Vinni Dec 17 '20 at 13:44

2 Answers2

0

var element = xdoc.Elements("Source").FirstOrDefault();

Given your provided XML elements will always be null and so you do nothing with your XML and that's why the result looks like the input.

Reason1: Elements() is looking for direct children only and <Source> is not a direct child in your doc.

See https://learn.microsoft.com/en-us/dotnet/api/system.xml.linq.xcontainer.elements?view=net-5.0

Reason2: <Source> tag has a different namespace than the doc itself and so the query is looking in the wrong namespace.

Solution:

XNamespace ns = "http://www.acm.nl/DataModel/2018/09";
var element = xdoc.Descendants(ns + "Source").FirstOrDefault();

See https://learn.microsoft.com/en-us/dotnet/api/system.xml.linq.xcontainer.descendants?view=net-5.0 which is searching for children including their children.

If you expect a node to exist, I'd also recommend to use First() instead of FirstOrDefault(). This way you'll get an exception that would have shown you the reason for your problem.

Christoph Lütjen
  • 5,403
  • 2
  • 24
  • 33
0

You can try to modifty XML Data by using XPathNavigator.

Here is a simple demo you can refer to.

http://www.acm.nl/DataModel/2018/09 is the xmlns of MessageId.

XmlDocument document = new XmlDocument();
document.Load("test.xml");
XPathNavigator navigator = document.CreateNavigator();

XmlNamespaceManager manager = new XmlNamespaceManager(navigator.NameTable);
manager.AddNamespace("id", "http://www.acm.nl/DataModel/2018/09");

foreach (XPathNavigator nav in navigator.Select("//id:Source", manager))
{
    nav.SetValue("Tessssssst");
}

document.Save(@"new.xml");
大陸北方網友
  • 3,696
  • 3
  • 12
  • 37
  • @Vinni Glad to hear that. If this answer helps, maybe you can [vote on / accept it](https://stackoverflow.com/help/someone-answers). – 大陸北方網友 Dec 21 '20 at 01:31
  • @Vinni To get a random number, does this [answer](https://stackoverflow.com/a/2706537/8335151) help you? – 大陸北方網友 Jan 12 '21 at 09:45
  • I know I already accepted this answer which helped me a lot. But maybe you have some extra suggestions on this, if I want the 'nav.SetValue("Tessssssst")' to be a random number between 100000000 and 999999999. Thanx in advance. if needed I will create a new topic about this. – Vinni Jan 12 '21 at 09:47
  • thanx I will take a look. – Vinni Jan 12 '21 at 09:49