php dom Xml 遍历元素保留子元素
php dom Xml loop throught elements preserve childrens
所以我有一个 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 return 'live' 列表,如果您更改 DOM,它们也会更改。您可以使用 iterator_to_array() 将它们复制到数组中。
这里不仅有元素节点。注释、cdata 部分和文本(甚至只包含空格)也是节点。如果你迭代 $childNodes 你将不得不验证 DOMNode::$nodeType.
不要使用 DOMDocument::createElement() 的第二个参数。它有一个破碎的转义。创建一个文本节点并附加它。
如果您使用 Xpath 获取节点,1 和 2 将消失。
$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。 PHP 支持 XSLT ext/xsl
.
所以我有一个 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 return 'live' 列表,如果您更改 DOM,它们也会更改。您可以使用 iterator_to_array() 将它们复制到数组中。
这里不仅有元素节点。注释、cdata 部分和文本(甚至只包含空格)也是节点。如果你迭代 $childNodes 你将不得不验证 DOMNode::$nodeType.
不要使用 DOMDocument::createElement() 的第二个参数。它有一个破碎的转义。创建一个文本节点并附加它。
如果您使用 Xpath 获取节点,1 和 2 将消失。
$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。 PHP 支持 XSLT ext/xsl
.