Подтвердить что ты не робот

Xpath для выбора следующего брата

У меня есть фрагмент HTML:

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

Я хочу найти все места, где структура неверна, т.е. тег dd после тега dt.

Я пробовал это:

//dt/following-sibling::dt

но это не работает. Любые предложения?

4b9b3361

Ответ 1

ИЗМЕНИТЬ, как отмечено @Gaim, моя оригинальная версия не смогла захватить терминал 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();

Вывод - это те dt узлы, у которых нет сразу dd:

<dt>name2</dt>
<dt>name4</dt>
<dt>name6</dt>

То, что мы здесь делаем, говорит:

//dt

Все dt узлы, где угодно....

[not(following-sibling::*[1]

.... так, что это не тот случай, когда их первый следующий брат (что бы он ни назывался)....

[self::dd]]

... называется dd.

Ответ 2

Я не уверен, что понимаю вас, но есть мое решение. Этот XPath соответствует ALL <dt>, за которым не следует <dd>. Итак, существует тестовая структура

<xml>
  <dt>name</dt> <!-- match -->

  <dt>name2</dt>
  <dd>value2</dd>

  <dt>name</dt>
  <dd>value</dd>

  <dt>name2</dt>  <!-- match -->
</xml>

Существует XPath

//dt[ name( following-sibling::*[1] ) != 'dd' ]

или

//dt[  not( following-sibling::*[1]/self::dd ) ]

они делают то же самое