Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xpath for choosing next sibling

Tags:

I have piece of HTML like this:

<dt>name</dt>
<dd>value</dd>
<dt>name2</dt>
<dd>value2</dd>

I want to find all places where the structure is incorrect, meaning there is no dd tag after dt tag.

I tried this:

//dt/following-sibling::dt

but this doesn't work. Any suggestions?

like image 775
Ula Krukar Avatar asked Jan 19 '10 09:01

Ula Krukar


People also ask

How can I get next sibling in XPath?

To traverse to the next sibling, we have to use the following-sibling concept in xpath. This will allow us to traverse to the next sibling from the present sibling of the same parent. Let us try to move from the first child<h1> of parent <div> to the second <h2> as in the above image.

What is following-sibling in XPath?

XPath using Following-Sibling As the term signifies, siblings are those nodes that share the same parent or are at the same level. Hence, Following-Sibling will return you the node at the same level and after the current node.


1 Answers

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.

like image 189
AakashM Avatar answered Nov 05 '22 00:11

AakashM