У меня здесь немного странный вопрос, но он полностью меня озадачил. Как бы то ни было, это связано с тем, что я не могу придумать правильные условия для поиска, поэтому на этот вопрос можно ответить на StackOverflow, но я не могу его найти.
У нас есть система проверки, которая позволяет нам делать страницу и аннотировать ее. Мы можем отправить страницу нашим клиентам, и они могут делать заметки, прежде чем отправлять их обратно. По большей части это прекрасно работает. Проблема возникает, когда мы пытаемся использовать систему шаблонов JavaScript, аналогичную Handlebars. Мы склонны иметь шаблоны скриптов на нашей странице, которые выглядят примерно так:
<script type="client/template" id="foo-div"> <div>#foo#</div> </script>
Мы можем использовать это в наших скриптах для создания разметки внутри шаблона, заменив #foo#
на правильные данные.
Проблема возникает, когда мы пытаемся внедрить это в нашу систему проверки. Поскольку нам нужно очистить страницу, чтобы мы могли визуализировать наш домен, мы используем DOMDocument
PHP для синтаксического анализа HTML, чтобы мы могли легко его модифицировать (добавляя к внешним ссылкам и т. Д. Такие вещи, как target="_blank"
). Когда мы пытаемся запустить наш DOMDocument
помощью DOMDocument
, он анализирует его странно (возможно, рассматривая его как недопустимый XML) и вызывает проблемы на странице. Чтобы лучше проиллюстрировать это, вот пример в PHP:
<?php error_reporting(E_ALL); ini_set('display_errors', 1); $html = '<!DOCTYPE html>'. '<html>'. '<head></head>'. '<body>'. '<script type="client/template" id="foo-div"><div>#foo#</div></script>'. '</body>'. '</html>'; $dom = new DOMDocument(); libxml_use_internal_errors(true); try { $html = $dom->loadHTML($html); } catch (Exception $e) { throw new Exception('Invalid HTML on the page has caused a parsing error'); } if ($html === false) { throw new Exception('Unable to properly parse page'); } $dom->preserveWhiteSpace = false; $dom->formatOutput = false; echo $dom->saveHTML();
Этот скрипт создает код, похожий на HTML ниже, и, похоже, не содержит никаких исключений.
<!DOCTYPE html> <html> <head></head> <body><script type="client/template" id="foo-div"><div>#foo#</script></body> </html>
Мой вопрос: кто-нибудь знает, как я могу заставить DOMDocument
PHP оставить шаблонный script
тег? Есть ли параметр или плагин, который я могу использовать для того, чтобы DOMDocument
содержимое тега script
с атрибутом type
как обычный текст, как и браузеры?
редактировать
Я закончил работу с решением Alf Eaton или разобрал строку как XML. Однако не все теги HTML были самозакрыты и вызвали проблемы. Я отправляю полное решение здесь, в случае, если кто-то сталкивается с одной и той же проблемой:
/** * Inserts a new string into an old string at the specified position. * * @param string $old_string Old string to modify. * @param string $new_string New string to insert. * @param int $position Position at which the new string should be inserted. * @return string Old string with new string inserted. * @see http://stackoverflow.com/questions/8251426/insert-string-at-specified-position */ function str_insert($old_string, $new_string, $position) { return substr($old_string, 0, $position) . $new_string . substr($old_string, $position); } /** * Inspects a string of HTML and closes any tags that need self-closing in order * to make the HTML valid XML. * * @param string $html Raw HTML (potentially invalid XML) * @return string Original HTML with self-closing slashes added. */ function self_close($html) { $fixed = $html; $tags = array('area', 'base', 'basefont', 'br', 'col', 'frame', 'hr', 'img', 'input', 'link', 'meta', 'param'); foreach ($tags as $tag) { $offset = 0; while (($offset = strpos($fixed, '<' . $tag, $offset)) !== false) { if (($close = strpos($fixed, '>', $offset)) !== false && $fixed[$close - 1] !== '/') { $fixed = str_insert($fixed, '/', $close); } $offset += 1; // Prevent infinite loops } } return $fixed; } // When parsing the original string: $html = $dom->loadXML(self_close($html));