Использование оператора OR в выражении XPath - PullRequest
0 голосов
/ 10 июня 2019

Я хочу использовать условие ИЛИ (более одного раза) в своем выражении XPath, чтобы извлечь то, что мне нужно в содержимом, до того, как встретится определенная строка, такая как «Справочник», «Для получения дополнительной информации» и т. Д. Что у меня естьниже, кажется, не работает, когда я использую его в PHP, но он работает на тестере XPath.Любая помощь будет принята с благодарностью.Кроме того, может ли выражение быть сжатым?

"//p[starts-with(normalize-space(),'Reference')]/preceding-sibling::p | 
//p[starts-with(normalize-space(), 'For more')]/preceding-sibling::p | 
//p[starts-with(normalize-space(),'Something')]/preceding-sibling::p"

Вот пример:

<root>
    <main>
        <article>
            <p>
               The stunning increase in homelessness announced in Los Angeles 
               this week — up 16% over last year citywide — was an almost  an 
               incomprehensible conundrum given the nation's booming economy 
               and the hundreds of millions of dollars that city, county and 
               state officials have directed toward the problem.
            </p>
            <p>
                "We cannot let a set of difficult numbers discourage us 
                or weaken our resolve" Garcetti said.
            </p>
            <p>
                For more information: Maeve Reston, CNN
            </p>
        </article>
    </main>
</root>

Результат, который я ищу, будет следующим:

<p>
    The stunning increase in homelessness announced in Los Angeles
    this week — up 16% over last year citywide — was an almost  an
    incomprehensible conundrum given the nation's booming economy
    and the hundreds of millions of dollars that city, county and
    state officials have directed toward the problem.
</p>
<p>
    "We cannot let a set of difficult numbers discourage us
    or weaken our resolve" Garcetti said.
</p>

Ответы [ 2 ]

1 голос
/ 10 июня 2019

Трубка не совсем "ИЛИ" - она ​​позволяет использовать несколько альтернативных выражений.Вы можете сравнить его с UNION в SQL.Но это работает в PHP.

$document = new DOMDocument();
$document->loadXML($xml);
$xpath = new DOMXpath($document);

$expression = 
    "//p[starts-with(normalize-space(), 'Reference')]/preceding-sibling::p | 
     //p[starts-with(normalize-space(), 'For more')]/preceding-sibling::p | 
     //p[starts-with(normalize-space(), 'Something')]/preceding-sibling::p";

foreach ($xpath->evaluate($expression) as $node) {
    echo $document->saveXML($node);
}

Однако "или" разрешено в условиях Xpath, фактически:

$expression = 
    "//p[
      starts-with(normalize-space(), 'Reference') or 
      starts-with(normalize-space(), 'For more') or 
      starts-with(normalize-space(), 'Something')
    ]/preceding-sibling::p";

foreach ($xpath->evaluate($expression) as $node) {
    echo $document->saveXML($node);
}

Демонстрация: https://3v4l.org/9SMJq

0 голосов
/ 10 июня 2019

Normalize-space () здесь не сработает, потому что вы пытаетесь найти подстроку. Лучше использовать contains.Try, следуя xpath.

//p[contains(., 'For more')]/preceding-sibling::p

Пример или предложение, основанное на строке.

//p[contains(., 'For more')]/preceding-sibling::p|//p[contains(., 'information')]/preceding-sibling::p|//p[contains(., 'CNN')]/preceding-sibling::p
...