I имеет следующую структуру, где дочерние узлы находятся в случайном порядке:Как выбрать текст() сразу после элемента условно в XPath?
<span id="outer">
<div style="color:blue">51</div>
<span class="main">Gill</span>$500
<span style="color:red">11</span>
<span></span>James
<div style="color:red">158</div>
<div class="sub">Mary</div>
</span>
Я пытаюсь соединить строки вместе (оставляя пространство между ними) на основе условий:
- Если цвет стиля «blue», затем добавьте значение узла в строку
- Если класс является «основным», то добавьте значение узла в строку
- Весь текст(), не заключенный в теги, будет добавлен в строку, но в порядке обхода всех ребенок узлы.
Пример вывода для вышеуказанной структуры должно быть:
51 Gill $500 James
Я написал следующее в PHP для обхода элементов. Можно пропустить чтение этой части, если она многословна. Основной акцент делается на $ выражение для выбора значения текста узла(), если оно сразу происходит после того, как элемент:
$nodes = $xpath->query("//span[@id='outer']/*");
$str_out = "";
foreach($nodes as $node)
{
if($node->hasAttribute('class')
{
if($node->getAttribute('class')=="main")
$str_out .= $node->nodeValue . " ";
}
else if($node->hasAttribute('style')
{
$node_style = $node->getAttribute('style');
preg_match('~color:(.*)~', $node_style, $temp);
if($temp[1] == "red")
$str_out .= $node->nodeValue . " ";
}
// Now evaluate if the IMMEDIATELY next sibling is text()
$next_node = $xpath->query('.//following-sibling::*[1]', $node);
if($next_node->length)
{
$next_node = $next_node->item(0);
$next_node_name = $next_node->nodeName;
$next_node_value = $next_node->nodeValue;
$current_node_name = $node->nodeName;
$expression = ".//following-sibling::text()[1][preceding-sibling::".$current_node_name." and following-sibling::".$next_node_name."[contains(text(),'".$next_node_value."')]]";
$text_node = $xpath->query($expression, $node);
if($text_node->length)
{
$str_out .= $text_node->item(0)->nodeValue . " ";
}
}
}
echo $str_out;
Основное внимание, как упоминалось ранее, является захват текста значения узлов() если происходит сразу после элемента. Я хочу написать выражение XPATH, которое делает следующее: 1. Выберите первый узел text() после элемента 2. Проверьте, находится ли этот узел text() между самим узлом (существующим узлом) и сразу следующим узлом ,
К примеру, в этом блоке:
<span></span>James
<div style="color:red">158</div>
Джеймс находится между пролетами и Div узлов. Поэтому мы добавляем его в строку.
Но в этом блоке:
<span style="color:red">11</span>
<span></span>James
<div style="color:red">158</div>
Джеймс все равно будет выбран следующий-родственного [1] заявление относительно первого элемента диапазона (с цветом: красный)
это не должно быть добавлен.
Пожалуйста, посмотрите мое выражение $ в PHP-коде, где я пытаюсь захватить этот процесс, но он не работает.
$expression = ".//following-sibling::text()[1][preceding-sibling::".$current_node_name." and following-sibling::".$next_node_name."[contains(text(),'".$next_node_value."')]]";
Благодаря тонну @KeithHall. Он отлично работает! Я не знал о funciton node() в next-sibling :: node() [1]. Еще раз спасибо за быстрый ответ! –
Также @KeithHall, очень ценю, что вы выписываете код, тестируете его и даете четкие объяснения для каждого шага. –