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

У меня есть часть HTML как это:

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

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

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

//dt/following-sibling::dt

но это не работает. Какие-либо предложения?

20
задан abatishchev 7 August 2015 в 06:03
поделиться

2 ответа

Отредактируйте Как отмечено @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();

Выход

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 .

16
ответ дан 30 November 2019 в 00:27
поделиться

Я не уверен, что я понимаю вас, но есть мое решение. Это XPath соответствует всем

, которые не сопровождаются
. Таким образом, есть тестовая структура

<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 ) ]

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

16
ответ дан 30 November 2019 в 00:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: