Как в PHP с помощью класса DomDocument добавить новый атрибут к узлу, чтобы он стал первым в списке атрибутов?

У меня есть узел: <br/> <code class="html">&lt;p  data-attr-1="foo"  data-attr-2="bar"  &gt;</code> <br/> <br/> Я создал узел атрибута: <br/> <pre><code class="php">$class_attr_node = $dom-&gt;createAttribute( 'class' );</code></pre> <br/> <br/> Как правильно добавить этот созданный узел <code>$class_attr_node</code> в качестве первого атрибута, чтобы итоговый код выглядел так: <br/> <pre><code class="html">&lt;p  class="some-class"  data-attr-1="foo"  data-attr-2="bar"  &gt;</code></pre> <br/> <br/> Я пробовал следующий код: <br/> <code class="html">$node-&gt;attributes-&gt;prepend( $class_attr_node );</code> <br/> Однако он не работает.
  • 2 октября 2024 г. 17:14
Ответы на вопрос 2
В PHP с использованием класса `DOMDocument` невозможно добавить атрибут прямо в начало списка атрибутов, поскольку `DOMDocument` не поддерживает прямого метода для вставки атрибута в определенное место. Вместо этого, вам нужно создать новый атрибут, затем клонировать все существующие атрибуты и присоединить их после нового атрибута.

Вот пример того, как это можно сделать:

```php
<?php
// Создаем новый документ DOM
$dom = new DOMDocument();

// Загрузка HTML
$dom->loadHTML('<p data-attr-1="foo" data-attr-2="bar"></p>');

// Получаем узел, к которому будем добавлять атрибут
$node = $dom->getElementsByTagName('p')->item(0);

// Создаем новый атрибут
$class_attr_node = $dom->createAttribute('class');
$class_attr_node->value = 'some-class'; // Устанавливаем значение атрибута

// Добавляем новый атрибут
$node->setAttributeNode($class_attr_node);

// Теперь получится устойчивый обход атрибутов для перестановки
$node_attrs = [];
foreach ($node->attributes as $attr) {
    $node_attrs[] = $attr; // Сохраняем существующие атрибуты
}

// Удаляем все атрибуты, чтобы их добавить в нужном порядке
foreach ($node_attrs as $attr) {
    $node->removeAttribute($attr->name);
}

// Сначала добавляем новый атрибут, а затем существующие
$node->setAttributeNode($class_attr_node);
foreach ($node_attrs as $attr) {
    $node->setAttribute($attr->name, $attr->value);
}

// Выводим результат
echo $dom->saveHTML();
?>
```

В этом коде мы:

1. Создаем новый атрибут `class`.
2. Сохраняем все существующие атрибуты в массив.
3. Удаляем существующие атрибуты из узла, чтобы иметь возможность при добавлении задать новый порядок.
4. Сначала добавляем новый атрибут, после чего добавляем существующие в новом порядке.

В результате `<p>` элемент получает новый атрибут `class` в самом начале, и атрибуты выставляются в нужном порядке. После выполнения данного кода, HTML будет следующим:

```html
<p class="some-class" data-attr-1="foo" data-attr-2="bar"></p>
```
<pre><code class="php">$dom = new DOMDocument('1.0', 'utf-8');
$dom-&gt;loadHTML($html);
$xpath = new DOMXPath($dom);
$paragraphs = $xpath-&gt;query('/html/body/p');
foreach ($paragraphs as $paragraph) {
    $attributes = $paragraph-&gt;attributes;
    $first = $attributes-&gt;item(0);
    $new_attr = $dom-&gt;createAttribute('class');
    $new_attr-&gt;value = 'some-class';
    $paragraph-&gt;insertBefore($new_attr, $first);
}
var_dump($dom-&gt;saveHTML());</code></pre>
Похожие вопросы