получение только последующих братьев и сестер того же типа с использованием xpath и simplexml

Мне нужно проанализировать список определений html следующим образом:

<dl>
    <dt>stuff</dt>
        <dd>junk</dd>
        <dd>things</dd>
        <dd>whatnot</dd>
    <dt>colors</dt>
        <dd>red</dd>
        <dd>green</dd>
        <dd>blue</dd>
</dl>

Так что я могу получить такой ассоциативный массив:

[definition list] =>
    [stuff] =>
        [0] => junk
        [1] => things
        [2] => whatnot
    [colors] =>
        [0] => red
        [1] => green
        [2] => blue

Я использую DOMDocument -> loadHTML() для импорта строки HTML в объект, а затем simplexml_import_dom() для использования расширений simplexml, в частности xpath.

Проблема, с которой я столкнулся, связана с синтаксисом XPath для запроса всех элементов <dd>, которые являются последовательными и не разбиты на <dt>.

Поскольку элементы <dd> не считаются дочерними элементами <dt>, я не могу просто выполнить цикл запроса всех dt и запросить все dd.

Поэтому я думаю, что мне нужно сделать запрос для первого dd брата и сестры каждого dt, а затем для всех dd братьев и сестер этого первого dd.

Но из руководств по XPath мне не ясно, возможно ли это. Можете ли вы сказать «последовательное совпадение братьев и сестер»? Или я вынужден перебирать каждого потомка исходного dl и перемещаться по любым dts и dd по мере их появления?


person Anthony    schedule 21.12.2009    source источник


Ответы (1)


Конечно, есть способы найти последовательных совпадающих братьев и сестер в XPath, но это было бы относительно сложно, и, поскольку вам все равно придется обрабатывать каждого ребенка, вы могли бы просто перебрать их, как вы упомянули. Это будет проще и эффективнее, чем перебирать <dt/>, а затем искать братьев и сестер.

$dl = simplexml_load_string(
    '<dl>
        <dt>stuff</dt>
            <dd>junk</dd>
            <dd>things</dd>
            <dd>whatnot</dd>
        <dt>colors</dt>
            <dd>red</dd>
            <dd>green</dd>
            <dd>blue</dd>
    </dl>'
);

$list = array();
foreach ($dl->children() as $child)
{
    switch (dom_import_simplexml($child)->localName)
    {
        case 'dt':
            $k = (string) $child;
            break;

        case 'dd':
            $list[$k][] = (string) $child;
            break;
    }
}
person Josh Davis    schedule 21.12.2009