Итак, у меня есть XML-файл, как
<cars>
<id>1</id>
<photos>
<img>http://sit.com/img.jpg</img>
<img>http://sit.com/img.jpg</img>
<img>http://sit.com/img.jpg</img>
<img>http://sit.com/img.jpg</img>
</photos>
</cars>
Поэтому мне нужно изменить все имя тега на альтернативное, и мне нужно получить что-то вроде
<cars>
<ex_id>1</ex_id>
<images>
<photo>http://sit.com/img.jpg</photo>
<photo>http://sit.com/img.jpg</photo>
<photo>http://sit.com/img.jpg</photo>
<photo>http://sit.com/img.jpg</photo>
</images>
</cars>
Мой код
foreach ($dom->getElementsByTagName('cars') as $item) {
for ($i = 0; $i < $item->childNodes->length; ++$i) {
$car = $item->childNodes->item($i);
$NewElement = $dom->createElement($newName,$value);
$car->parentNode->replaceChild($NewElement->cloneNode(TRUE), $car);
}
}
Сделать что-то подобное
<cars>
<ex_id>1</ex_id>
<images/>
</cars>
Так что порезали всех детей <photos>
, поэтому мой вопрос, как сохранить детей, а также изменить теги детей от <img>
в <photo>
Вот несколько вопросов:
getElementByTagName () и $ childNodes возвращают «живые» списки, они меняются, если вы меняете DOM. Вы можете использовать iterator_to_array (), чтобы скопировать их в массив.
Здесь находятся не только узлы элементов. Комментарии, разделы cdata и текст (даже содержащий только пробелы) также являются узлами. Если вы перебираете $ childNodes, вам нужно будет проверить DOMNode :: $ nodeType.
Не используйте второй аргумент DOMDocument :: createElement (). У него сломан побег. Создайте текстовый узел и добавьте его.
1 и 2 уходят, если вы используете Xpath для извлечения узлов.
$dom = new DOMDocument();
$dom->loadXml($xml);
$xpath = new DOMXPath($dom);
foreach ($xpath->evaluate('/cars/images/img') as $photo) {
$newNode = $dom->createElement('photo');
$newNode->appendChild($dom->createTextNode($photo->textContent));
$photo->parentNode->replaceChild($newNode, $photo);
}
echo $dom->saveXml();
Выход:
<?xml version="1.0"?>
<cars>
<ex_id>1</ex_id>
<images>
<photo>http://sit.com/img.jpg</photo>
<photo>http://sit.com/img.jpg</photo>
<photo>http://sit.com/img.jpg</photo>
<photo>http://sit.com/img.jpg</photo>
</images>
</cars>
Изменение документа DOM часто является плохой идеей. Проще извлечь данные из исходного документа и создать новый целевой документ:
$source = new DOMDocument();
$source->loadXml($xml);
$xpath = new DOMXPath($source);
$target = new DOMDocument();
$target->formatOutput = TRUE;
$cars = $target->appendChild($target->createElement('cars'));
$cars
->appendChild($target->createElement('ex_id'))
->appendChild(
$target->createTextNode(
$xpath->evaluate('string(/cars/id)')
)
);
$images = $cars->appendChild($target->createElement('images'));
foreach ($xpath->evaluate('/cars/photos/img') as $photo) {
$images
->appendChild($target->createElement('photo'))
->appendChild($target->createTextNode($photo->textContent));
}
echo $target->saveXml();
Выход:
<?xml version="1.0"?>
<cars>
<ex_id>1</ex_id>
<images>
<photo>http://sit.com/img.jpg</photo>
<photo>http://sit.com/img.jpg</photo>
<photo>http://sit.com/img.jpg</photo>
<photo>http://sit.com/img.jpg</photo>
</images>
</cars>
Вот язык, посвященный преобразованию XML — XSLT. XSLT поддерживается PHP ext/xsl
,
Других решений пока нет …