简体   繁体   中英

Delete Node out of an attribute XML C#

as i said in the Title i want to delete the node when i get a specific value out of an attribute. (in this case "install" out of the attribute "dependencyType")

Xml File:

<dependency>
<dependentAssembly dependencyType="preRequisite">
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly dependencyType="install">
</dependentAssembly>
</dependency>

How it shall look like(after i ran through):

<dependency>
<dependentAssembly dependencyType="preRequisite">
</dependentAssembly>
</dependency>

i want to remove the node (in this case "dependency" when i get in the attribute "dependencytype" the value "install").

i tried two things 1st Code:

private void DeleteXmlPopulates()
    {
        string filepath = "C:\Example\Example.exe.manifest";
        XmlDocument doc = new XmlDocument();
        doc.Load(filePath);
        using (XmlReader reader = XmlReader.Create(filePath))
        {
            while (reader.Read())
            {
                if (reader.Name == "dependency")
                {
                    if (reader.GetAttribute("dependencyType") == "install")
                    {
                       //here i shall get the current Node-name and .Remove(); it
                    }
                }
            }
        }

2nd Code:

        private void DeleteXmlPopulates()
    {
        string filepath = "C:\Example\Example.exe.manifest";
        XmlDocument doc = new XmlDocument();
        doc.Load(filePath);
        var xml = XElement.Load(File.OpenRead(filePath));

        var elementsToDelete = xml.Descendants().Where(x => x.Name == "dependentAssembly" && x.Attribute("dependencyType") != null && x.Attribute("dependencyType").Value == "install");

        foreach (var xElement in elementsToDelete)
        {
            xElement.Remove();
        }
        xml.Save(filePath);
    }

The problem is in the first one is given in the code

The problem is in the second one is that if i get "elementsToDelete" for the foreach-loop and it comes back there arent any "elementsToDelete" so it skips the for each, after all of that, the programm tries to save (xml.save(filepath);) but it gets an exception that its already in use.

What shall i do? Why is it like that?

constructive criticism is Welcome :) correct everytihng you want in my question :) I hope its clear :)

This is the problem in the second code:

XmlDocument doc = new XmlDocument();
doc.Load(filePath);
var xml = XElement.Load(File.OpenRead(filePath));

For some reason, you're loading the XML document twice in this (and then ignoring doc ) - but you're leaving a stream open (the stream returned by File.OpenRead ). Change this code to just:

var xml = XElement.Load(filePath);

and it should be fine. You can simplify the rest of the code using the Remove extension method though:

xml.Descendants()
   .Where(x => x.Name == "dependentAssembly" && 
               (string) x.Attribute("dependencyType") == "install")
   .Remove();

Note that casting XAttribute to string just returns null if the attribute doesn't exist (ie if you call it with a null reference).

So your who method becomes:

private void DeleteXmlPopulates()
{
    string filepath = "C:\Example\Example.exe.manifest";
    var xml = XElement.Load(filePath);
    xml.Descendants()
       .Where(x => x.Name == "dependentAssembly" && 
                   (string) x.Attribute("dependencyType") == "install")
       .Remove();
    xml.Save(filePath);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM