2015-11-28 4 views
1

У меня есть следующий HTML-документ:XPath Объединить Node Тексты на основе Условия

<div> 
    <span>Line 1</span> 
    <p> 
    <span class='inline'>This</span> 
    text should 
    <span class='inline'>be in</span> 
    one 
    <span class='inline'>line</span> 
    <span class='inline'>all together</span> 
    </p> 
    <em> 
    <span class='inline'>This</span> 
    line 
    <span class='inline'>too</span> 
    </em> 
    <a href="#">Line 4</a> 
    <div> 
    <p> 
     <span class='inline'>This fourth</span> 
     line 
     <span class='inline'>too</span> 
    </p> 
    </div> 
    <script type="text/javascript">//...</script> 
    <b></b> 
</div> 

Текст, который должен быть извлечен:

Line 1 
This text should be in one line all together 
This line too 
Line 4 
This fourth line too 

На данный момент я использую //div//descendant::*[not(self::script)]/text()[string-length() > 0] для извлечения текста.

Это приводит к следующему результату:

Line 1 
This 
text should 
be in 
one 
line 
all together 
This 
line 
too 
Line 4 
This fourth 
line 
too 

Как совместить тексты в случае класс «инлайн» используется? Или как я могу использовать текст родительского узла в случае, если класс «inline» был обнаружен внутри дочернего узла?

Обратите внимание, что это пример: Тег p и em может отличаться!

ответ

0

Возможно, вы смотрите на неправильную точку. Что совал мне в глаза, что вы ищете текстового содержимого любого дочернего DIV (здесь также корень) элемента - но для тега сценария и если он пуст:

/div/*[name() != "script" and string-length(normalize-space())] 

Мой XPath пример также делает нормализацию пространства. Например. если <b></b> будет <b> </b> или с некоторым перерывом, он также будет считаться пустым.

Чтение DOMNode::$textContent и нормализацию пространства с ней дает следующие результаты:

string(6) "Line 1" 
string(44) "This text should be in one line all together" 
string(13) "This line too" 
string(6) "Line 4" 
string(20) "This fourth line too" 

Вот быстрый PHP пример кода demonstrating this:

<?php 

$buffer = <<<XML 
<div> 
    <span>Line 1</span> 
    <p> 
    <span class='inline'>This</span> 
    text should 
    <span class='inline'>be in</span> 
    one 
    <span class='inline'>line</span> 
    <span class='inline'>all together</span> 
    </p> 
    <em> 
    <span class='inline'>This</span> 
    line 
    <span class='inline'>too</span> 
    </em> 
    <a href="#">Line 4</a> 
    <div> 
    <p> 
     <span class='inline'>This fourth</span> 
     line 
     <span class='inline'>too</span> 
    </p> 
    </div> 
    <script type="text/javascript">//...</script> 
    <b></b> 
</div> 
XML; 

$xml = simplexml_load_string($buffer); 
$result = $xml->xpath('/div/*[name() != "script" and string-length(normalize-space())]'); 
foreach ($result as $node) { 
    $text = dom_import_simplexml($node)->textContent; 
    $text = preg_replace(['(\s+)u', '(^\s|\s$)u'], [' ', ''], $text); 
    var_dump($text); 
} 
Смежные вопросы