Vani
Vani

Reputation: 1353

Issue in removing all the nodes from XML file using LINQ

I am trying to remove all the nodes from the XML file. But it's removing the root node open tag also .Using C# anf Linq

Input:

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!--Log the error count and error message-->
<root>
    <ErrData>
        <Count>1</Count>
        <Timestamp>2011-11-21T11:57:12.3539044-05:00</Timestamp>
     </ErrData>
     <ErrData>max of 20 ErrData elements</ErrData>
 </root>

Expected OP:

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!--Log the error count and error message-->
<root>
</root>

Actual OP:EDITED

<?xml version="1.0" encoding="utf-8" standalone="no"?>
    <!--Log the error count and error message-->
<root />

Code :

XDocument docs = XDocument.Load(path);
try
{                   
    docs.Descendants("ErrData").Remove();
}

CODE:

Below is the code i am using ,the concept is the error count and timestamp are logged into XML file.Once its reached the threshold value,email will be send by function and remove all the nodes from the xml. Then when the next error comes it will start entering in to the xml file as below,

XDocument doc = null;
XElement el;
if (!System.IO.File.Exists(path))
{

    doc = new XDocument(new XDeclaration("1.0", "utf-8", "no"));
    el = new XElement("root");
    //el = new XElement("root");
    XComment comment = new XComment("Log the error count and error message");
    doc.Add(comment);
}
else
{
    doc = XDocument.Load(path);
}
XElement p1 = new XElement("ErrData");
XElement p1Count = new XElement("Count", eventCount);
XElement p1Windowsatrt = new XElement("Timestamp", windowStart);

p1.Add(p1Count );
p1.Add(p1Windowsatrt );

if (doc.Root != null)
{
    el = doc.Root;
    el.Add(p1);
}
else
{
    el = new XElement("root");
    el.Add(p1);
}


try
{
    doc.Add(el);//Line throwing the exeception

}
catch (Exception e)
{

}
finally
{
    doc.Save(path);
}

Upvotes: 4

Views: 1015

Answers (3)

Robert Rossney
Robert Rossney

Reputation: 96702

The confusion is in your very first sentence: "I am trying to remove all the nodes/elements from the XML file." Which one is it? Do you want to remove all nodes, or all elements?

There are five types of nodes in XML: elements, text, comments, processing instructions, and attributes. If you use "node" and "element" interchangeably, as you are here, you're going to have no end of trouble working with XML.

What you got, <root/>, is the correct output for code that removes all descendant nodes: it's a single element named root with no content.

What you expect,

<root>
</root>

is a single element named root that contains a child text node containing whitespace, probably a newline. The code you wrote removes all descendant nodes, not just descendant element nodes, and so it removed this text node as well.

Upvotes: 1

Ron Warholic
Ron Warholic

Reputation: 10074

<root /> is valid XML for a tag with no content (self-closing tags). If you absolutely need an opening and closing tag you need to put some content in the root node like a comment or text.

Upvotes: 1

Martin Honnen
Martin Honnen

Reputation: 167426

Use docs.Root.Nodes().Remove().

Upvotes: 1

Related Questions