Вставка xPath до и после - с DOM и PHP - PullRequest
1 голос
/ 11 января 2011

Мне нужно добавить класс в структуру HTML.

Мой класс называется " container " и должен начинаться сразу после (дочерний элемент ul и его simblings, а не внуков) и должен заканчиваться прямо перед закрытием того же элемента.код выглядит так:

<?php
$content = '
    <div class="sidebar-1">
        <ul>
            <li>
                <h4>Title</h4>
                <ul> 
                    <li><a href="http://www.test.com">Test</a></li> 
                    <li><a href="http://www.test.com">Test</a></li> 
                </ul> 
            </li> 
            <li>
                <p>Paragraf</p>
            </li> 
            <li>
                <h4>New title</h4>
                <ul> 
                    <li>Some text</li>
                    <li>Some text åäö</li>
                </ul> 
            </li> 
        </ul>
    </div>
';

$doc = new DOMDocument();
$doc->loadHTML($content);
$x = new DOMXPath($doc);

$start_text = '<div class="container">';
$end_text = '</div>';

foreach($x->query('//div/ul/li') as $anchor)
{
    $anchor->insertBefore(new DOMText($start_text),$anchor->firstChild);
}
echo $doc->saveXML($doc->getElementsByTagName('ul')->item(0));
?>

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

Результат должен быть

    <div class="sidebar-1">
        <ul>
            <li>
                <h4>Title</h4>
                <div class="content">
                    <ul> 
                        <li><a href="http://www.test.com">Test</a></li> 
                        <li><a href="http://www.test.com">Test</a></li> 
                    </ul>
                </div>
            </li> 
            <li>
                <div class="content">
                    <p>Paragraf</p>
                </div>
            </li> 
            <li>
                <h4>New title</h4>
                <div class="content">
                    <ul> 
                        <li>Some text</li>
                        <li>Some text åäö</li>
                    </ul> 
                </div>
            </li> 
        </ul>
    </div>

1 Ответ

2 голосов
/ 12 января 2011

Я не смог найти более элегантный способ переназначения всех детей, поэтому, думаю, это подойдет.Я думаю, что он получает то, что вам нужно.

(ПРИМЕЧАНИЕ: код обновлен, чтобы отразить дополнительные требования в комментариях.)

$doc = new DOMDocument();
$doc->loadHTML($content);
$x = new DOMXPath($doc);

foreach($x->query('//div/ul/li') as $anchor)
{
    $container = $doc->importNode(new DOMElement('div'));
    $container->setAttribute('class', 'container');

    $next = $anchor->firstChild;
    while ($next !== NULL) {
        $curr = $next;
        $next = $curr->nextSibling;

        if (($curr->nodeName != 'h4')
            || ($curr->attributes === NULL)
            || ($curr->attributes->getNamedItem('class') === NULL)
            || !preg_match('#(^| )title( |$)#', $curr->attributes->getNamedItem('class')->nodeValue)
        ) {
            $container->appendChild($anchor->removeChild($curr));
        }
    }

    $anchor->appendChild($container);
}

Что касается персонажакодирование, я возился с этим некоторое время, и это сложная проблема.Символы отображаются правильно при загрузке с loadXML(), но не с loadHTML().Есть обходной путь в комментариях , но это не красиво.Надеемся, что некоторые комментарии пользователей помогут вам найти подходящее решение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...