Почему PHP DOM не содержит косой черты на закрывающих тегах?

Я использую PHP DOM для загрузки html-шаблона, его изменения и вывода. Недавно я обнаружил, что самозакрывающиеся (пустые) теги не содержат закрывающей косой черты, даже если файл шаблона.

например

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"`"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> </head> <body> </body> </html> 

будет выглядеть так:

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> </head> <body> </body> </html> 

Является ли это ошибкой или настройкой, или проблемой doctype?

DOMDocument->saveHTML() берет ваш XML-DOM-файл и записывает его как HTML- DOMDocument->saveHTML() старой школы, а не XML. Вы не должны использовать saveHTML() вместе с доктриной XHTML, так как ее вывод не будет хорошо сформированным XML.

Если вы вместо этого используете saveXML() , вы получите правильный XHTML. Прекрасно обслуживать этот XML-вывод для совместимых со стандартами браузеров, если вы дадите ему заголовок Content-Type: application/xhtml+xml . Но, к сожалению, IE6-8 не сможет прочитать это, поскольку они все еще могут обрабатывать только HTML старой школы под типом text/html media.

Обычным компромиссным решением является использование text/html и использование «HTML-совместимого XHTML», как описано в Приложении C спецификации XHTML 1.0. Но, к сожалению, не существует DOMDocument->saveXHTML() PHP DOMDocument->saveXHTML() для создания правильного вывода для этого.

Есть несколько вещей, которые вы можете сделать, чтобы убедить saveXML() для создания HTML-совместимого вывода для некоторых распространенных случаев. Главное, что вы должны убедиться, что только элементы, определенные HTML4 как имеющие модель содержимого EMPTY ( <img> , и т. Д.), Действительно имеют пустой контент, вызывая самозакрывающийся синтаксис ( <img/> ) использоваться. Другие элементы не должны использовать самозакрывающийся синтаксис, поэтому, если они пусты, вы должны поместить пространство в свой текстовый контент, чтобы остановить их:

 <script src="x.js"/> <-- no good, confuses HTML parser and breaks page <script src="x.js"> </script> <-- fine 

Другой, на что нужно обратить внимание, это обработка встроенных элементов <script> и <style> , которые являются нормальными элементами в XHTML, но особыми элементами CDATA содержимого в HTML. Некоторые /*<![CDATA[*/.../*]]>*/ обязательны для того, чтобы любые < или & символы внутри них вели себя в основном – последовательно, но учтите, что вам все равно нужно избегать ]]> и </ последовательностей.

Если вы хотите действительно сделать это правильно, вам придется написать свой собственный сериализатор, совместимый с HTML-XHTML. Долгосрочный вариант, вероятно, будет лучшим вариантом. Но для небольших простых случаев взломать ваш вход так, чтобы он не содержал ничего, что могло бы вывести другой конец сериализатора XML как несовместимого с HTML, вероятно, является быстрым решением.

Это или просто сосать его и жить со старым школьным не-XML-HTML, очевидно.

проблема типа doctype, поскольку текст / html закрывающий косой черты не нужен, вам нужно только закрыть слэш, если это документ xhtml

отметил, что вы обновили, чтобы добавить в doctype, но PHP dom также смотрит на этот метатег, который у вас есть, а контент = «text / html; charset = utf-8» явно не основан на XML, это просто text / html 🙂

в стороне: DOM api также собирает чарсет оттуда

Это старый вопрос, но …
Как заявили другие, DOM PHP оставляет желать лучшего …
Вот regEx, чтобы закрыть теги «void», если вы так желаете

 $voidTags = array('area','base','br','col','command','embed','hr','img','input','keygen','link','meta','param','source','track','wbr'); $regEx = '#<('.implode('|', $voidTags).')(\b[^>]*)>#'; $html = preg_replace($regEx, '<\\1\\2 />', $html);