Как извлечь некоторые теги и заменить другие из XML с SimpleXML - PullRequest
0 голосов
/ 10 января 2012

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

Существует простой скрипт, который может конвертировать Markdown в HTML, но мне нужно сделать кое-что с HTML, как только это будет сделано:

  1. Мне нужно заменить все символы HTML внутри предварительного тега с помощью функции htmlentities (). (В моем блоге я пишу о коде, включая HTML, я только хочу отобразить этот HTML, а не анализировать его в браузере).

  2. Мне нужно извлечь весь простой текст, чтобы в конце я мог создать выдержки, которые не включают теги изображения или полутэги (или фрагменты кода в pre). *

Я думал, что у меня есть решение проблемы 2 с помощью следующего кода:

$xml = new SimpleXMLElement('<xml>' . $html . '</xml>');

$ xml теперь выглядит примерно так:

<xml>
  <p>some random text</p>
  <img src='image.jpg'>
  <p>some random text</p>
</xml>

это извлекает весь текст:

foreach($xml->{'p'} as $p){
echo $p . '<hr>';
}

Это работает, однако я также хочу, чтобы в него был включен весь текст, найденный в ul и ol (в том же порядке, в каком они появляются в XML. не могу найти, как проверить, является ли элемент ap, ul или ol.

И я не могу найти способ решить проблему 1, потому что я не знаю, как заменить содержимое в объекте XML, но оставляю все остальное нетронутым. (Или я упускаю что-то совершенно очевидное?)

1 Ответ

0 голосов
/ 13 января 2012

После долгих поисков я не смог найти именно то, что искал, используя синтаксический анализ XML, кроме того, что мне потребовалась пара других функций.Я решил проблему с REGEX, поскольку весь HTML-код сгенерирован мной.

Таким образом, приведенное здесь решение решает проблему моих исходных проблем + еще немного.

Эта функция берет часть содержимого(строка) и возвращает пару строк:

  • md = то же самое, что содержимое с угловыми скобками внутри pre, измененное на html-сущность (я пишу в блоге о HTML, но в моем сообщении для редактирования screen Я не хочу, чтобы html внутри pre анализировался.
  • html = все, что находится за пределами pre, равно Markdown'd, и каждый htmlchar внутри pre заменяется на html-сущность.
  • отрывок = текст сокращен до 300 символов, без каких-либо предварительных тегов (или их содержимого), без синтаксиса уценки или HTML-тегов.
  • meta = аналогично отрывку для 160 символов.

    <code>function prepareContent($content) {
    
        // I use this instead of htmlentities for the plain text, this prevents HTML to be parsed inside the edit screen
        // all HTML is served with htmlentities instead
        function removeAngleBrackets($str) {
            $str = str_replace('<','&lt;',$str);
            $str = str_replace('>','&gt;',$str);
            return $str;
        }
    
        $segments = preg_split('/(<\/?pre.*?>)/', $content, -1, PREG_SPLIT_DELIM_CAPTURE);
    
        // STATE MACHINE
        // borrowed from: http://stackoverflow.com/questions/1278491/howto-encode-texts-outside-the-pre-pre-tag-with-htmlentities-php#answer-1278575
    
        // this breaks when I nest pre's in pre's (unless I escape the <pre> myself), could be fixed though
    
        // $state = 0 if outside of a pre
        // $state = 1 if inside of a pre
        $state = 0;
    
        $plaintext = '';
        $html = '';
        $preless = '';
    
        // $html, $plaintext and $preless are all written in here
        foreach ($segments as &$segment) {
            if ($state == 0) {
                if (preg_match('#<pre[^>]*>#i',$segment)) {
                    //this is the pre opening tag
                    $state = 1; 
                    $html .= $segment;
                    $plaintext .= $segment;
                } else {
                    //this is outside the pre tag
                    $plaintext .= $segment;
                    $markdown = Markdown($segment);
                    $html .= $markdown;
                    $preless .= $markdown;
                }
            } else if ($state == 1) {
                if ($segment == '
    ') {// это предварительный закрывающий тег $ state = 0;$ html. = $ сегмент;$ обычный текст. = $ сегмент;} else {// это внутри пред тега $ plaintext. = removeAngleBrackets ($ сегмент);// сначала кодируем> в>, чтобы я мог перекодировать его вместе с другими символами // иначе мы получаем двойное кодирование, например: $ amp; gt;$ enti = html_entity_decode ($ сегмент);$ html. = htmlspecialchars ($ enti, ENT_QUOTES);}}} $ arr ['html'] = SmartyPants ($ html);$ arr ['md'] = $ обычный текст;// выдержка & meta // удалить все теги html (разметка уже преобразована в HTML) $ tagless = strip_tags ($ preless);function shrinkText ($ str, $ limit) {$ strlen = strlen ($ str);if ($ strlen> $ limit) {$ pos = strpos ($ str, '', $ limit);if ($ strlen> $ pos) {$ result = substr ($ str, 0, $ pos);}} вернуть $ результат?$ result: $ str;} // Мне нужно, чтобы smartypants отрывок к $ excerpt = shrinkText ($ tagless, 275).'(...)';$ arr ['excerpt'] = SmartyPants ($ excerpt);$ arr ['meta'] = shrinkText ($ tagless, 160);вернуть $ обр .;}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...