PHP DOM - доступ к вновь добавленным узлам - PullRequest
3 голосов
/ 14 ноября 2009

Я использую следующее, чтобы получить HTML-документ в DOM:

$dom = new domDocument('1.0', 'utf-8');
$dom->loadHTML($html)

и затем я добавляю новый элемент в элемент HTML:

$element = $dom->getElementById('mybox');
$f = $dom->createDocumentFragment();
$f->appendXML('<div id="newbox">foo</div>');
$element->appendChild($f);

Но если я теперь хочу манипулировать с #newbox, я не могу этого сделать, потому что не могу получить к нему доступ с помощью getElementById(). Для этого я должен сделать следующее (перезагрузка с новым HTML):

$html = $dom->saveHTML();
$dom->loadHTML($html)

Что отлично работает, но когда приходится делать это между каждой манипуляцией с домом, это становится дорогим с точки зрения производительности.

Есть ли лучший способ "обновить" DOM, чтобы он работал с вновь добавленными элементами?

Заранее спасибо! :)

Ответы [ 2 ]

1 голос
/ 14 ноября 2009

На подходе сохранения и загрузки вы также можете попробовать Document.normalizeDocument. Это должно исправить документ, как если бы он был циклически сохранен, без фактической сериализации. Единственное, что следует сделать, - это пересчитать атрибуты isID из типа документа, который, как вы надеетесь, будет 1008 * установлен в один из HTML типы документов (которые определяют id как атрибут идентификатора типа значения) по loadHTML.

(Существует также Element.setIdAttribute, который можно использовать для объявления одного экземпляра Attr, содержащего идентификатор, но это бесполезно для вас, так как вам придется его заполучить первый.)

Я не проверял это, хотя и не удивлюсь, если PHP не реализовал эту штуку DOM Level 3 Core должным образом. Согласно моей интерпретации спецификации для isId, я считаю, что она должна была уже автоматически определить определение типа id. (Моя собственная реализация DOM, безусловно, делает.) Но в этом случае ваш код работал бы. И я полагаю, что appendXML в конце концов является нестандартным методом, поэтому нечего сказать, что он должен разрешать определения типов, такие как loadXML или loadHTML.

Так что, возможно, обходной путь - лучший план. Вы можете использовать DOMXPath , чтобы выбрать элемент по атрибуту @id, а не по реальной идентичности как таковой. Конечно, это будет намного медленнее, чем getElementById, но, надеюсь, быстрее, чем normalizeDocument.

Или просто потерять цепочку XML-строк и, если можете, придерживаться методов DOM; тогда просто сохранить ссылку на созданный элемент. (Вы можете использовать вспомогательные функции, чтобы создавать элементы немного быстрее, если вы находите методы DOM слишком многословными для объема создаваемого контента.)

0 голосов
/ 14 ноября 2009

Единственное, что я знаю об этом, может справиться с этим очень хорошо ... красиво, это красивый суп питона. DOM полностью разбит на дерево разбора, которое вы можете добавить или убрать по своему усмотрению, возможно, вы сможете написать сценарий python для обработки html, а затем координировать сценарии с помощью базы данных или системного вызова. В качестве альтернативы стоит изучить javascript на стороне сервера.

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