You can try to address this in two steps, first get all nodes having only 'removeme` class attribute, then remove the entire class attribute from them :
//*[normalize-space(@class)='removeme']
Then in the next step, get all nodes having removeme class and some other classes, then strip out removeme from the class attribute :
//*[
normalize-space(@class)!='removeme'
and
contains(concat(' ', normalize-space(@class), ' '), ' removeme ')
]
the first condition in the XPath above means get all nodes that isn't processed in the step 1, and the 2nd condition is the equivalent XPath for css selector .removeme
Here is the complete console example :
var xml = @"<root>
<table class=""removeme""></table>
<table class=""removeme leaveme""></table>
<table class="" removeme ""></table>
</root>";
var doc = new HtmlDocument();
doc.LoadHtml(xml);
var removemeOnly = doc.DocumentNode.SelectNodes("//*[normalize-space(@class)='removeme']");
foreach (HtmlNode node in removemeOnly)
{
node.Attributes["class"].Remove();
}
var containsRemoveme =
doc.DocumentNode.SelectNodes("//*[normalize-space(@class)!='removeme' and contains(concat(' ', normalize-space(@class), ' '), ' removeme ')]");
foreach (HtmlNode node in containsRemoveme)
{
node.Attributes["class"].Value = node.Attributes["class"].Value.Replace("removeme", "");
}
//print formatted HTML output (don't use this for non XML-compliant HTML)
Console.WriteLine(XDocument.Parse(doc.DocumentNode.OuterHtml));
.DocumentNode.SelectNodes()function will give you a collection of nodes that you need to remove the attribute from.