I have piece of HTML like this:
I want to find all places where the
I am not sure that I understand you but there is my solution. This XPath matches ALL <dt>
which are not followed by <dd>
directly. So There is test structure
<xml>
<dt>name</dt> <!-- match -->
<dt>name2</dt>
<dd>value2</dd>
<dt>name</dt>
<dd>value</dd>
<dt>name2</dt> <!-- match -->
</xml>
There is the XPath
//dt[ name( following-sibling::*[1] ) != 'dd' ]
or
//dt[ not( following-sibling::*[1]/self::dd ) ]
they do same thing
EDIT as noted by @Gaim, my original version failed to capture a terminal dt
string xml = @"
<root>
<dt>name</dt>
<dd>value</dd>
<dt>name2</dt>
<dt>name3</dt>
<dd>value3</dd>
<dt>name4</dt>
<dt>name5</dt>
<dd>value5</dd>
<dt>name6</dt>
</root>
";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
XmlNodeList nodes =
doc.SelectNodes("//dt[not(following-sibling::*[1][self::dd])]");
foreach (XmlNode node in nodes)
{
Console.WriteLine(node.OuterXml);
}
Console.ReadLine();
Output is those dt
nodes that do not have a dd
immediately following them:
<dt>name2</dt>
<dt>name4</dt>
<dt>name6</dt>
What we are doing here is saying:
//dt
All dt
nodes, anywhere....
[not(following-sibling::*[1]
....such that it's not the case that their first following sibling (whatever it is called)....
[self::dd]]
...is called dd
.