[英]PHP - DOM - XML - Nodes with similar attribute manipulation
I have to manipulate a XML file with DOM 我必须使用DOM操作XML文件
This is my situation: 这是我的情况:
<mainnode>
<node1 name="aaa">
<subnode name="123456" />
</node1>
<node1 name="bbb">
<subnode name="28472" />
</node1>
<node1 name="aaa">
<subnode name="92328" />
</node1>
<node1 name="ccc">
<subnode name="53554" />
</node1>
<node1 name="ccc">
<subnode name="01928" />
</node1>
<node1 name="aaa">
<subnode name="39576" />
</node1>
<node1 name="ddd">
<subnode name="66666" />
</node1>
</mainnode>
And I want to group all my nodes reading the "name" attribute in <node1>
to obtain something like this for every "name" equal to another one: 我想将所有节点分组读取
<node1>
的“name”属性,为每个“name”获取类似于另一个的名称:
<mainnode>
<node1 name="aaa">
<subnode name="123456" />
<subnode name="92328" />
<subnode name="39576" />
</node1>
<node1 name="bbb">
<subnode name="28472" />
</node1>
<node1 name="ccc">
<subnode name="53554" />
<subnode name="01928" />
</node1>
<node1 name="ddd">
<subnode name="66666" />
</node1>
</mainnode>
What is the php code to do this kind of manipulation with dom? 用dom做这种操作的php代码是什么? is it possible?
可能吗?
You can do it like this (please ensure that your XML is normalized before): 您可以这样做(请确保您的XML之前已规范化):
// load the xml and prepare the dom
$dom = new DOMDocument('1.0', 'UTF-8');
// do not display parsing errors to the user
libxml_use_internal_errors(true)
// load xml
$dom->loadXML($string);
// optionally handle parsing errors provided in libxml_get_errors()
// store the node names
$nodeNames = array();
// get all nodes
$nodes = $dom->getElementsByTagName('node1');
foreach ($nodes as $node)
{
/* @var $node DOMElement */
$nodeName = $node->getAttribute("name");
if (isset($nodeNames[$nodeName]))
{
/* @var $previousNode DOMElement */
$previousNode = $nodeNames[$nodeName];
if ($node->hasChildNodes())
{
foreach ($node->childNodes as $childNode)
{
$previousNode->appendChild($childNode);
}
}
$node->parentNode->removeChild($node);
}
else
{
$nodeNames[$nodeName] = $node;
}
}
You can use the PHP XQuery extension in order to do this: 您可以使用PHP XQuery扩展来执行此操作:
let $data := (: your xml :)
return
element mainnode {
for $nodes in $data/node1
let $name := string($nodes/@name)
group by $name
return
element {$name} {
attribute name {$name},
for $node in $nodes
return $node/subnode
}
}
You can try the example live at http://www.zorba-xquery.com/html/demo#TuRqsG1GZewGQD3f0QhmsIpVmTc= Instructions on how to install the XQuery extension on PHP is available at http://www.zorba-xquery.com/html/entry/2011/12/27/PHP_Meets_XQuery 您可以在http://www.zorba-xquery.com/html/demo#TuRqsG1GZewGQD3f0QhmsIpVmTc上查看示例。有关如何在PHP上安装XQuery扩展的说明,请访问http://www.zorba-xquery.com/ HTML /项/ 2011/12月27日/ PHP_Meets_XQuery
Assuming $xml
holds your XML string ( demo ): 假设
$xml
保存您的XML字符串( 演示 ):
$dom = new DOMDocument;
$dom->preserveWhiteSpace = false;
$dom->loadXML($xml);
$xpath = new DOMXPath($dom);
// iterate all the subnodes
foreach ($xpath->query('/nodes/node1/subnode') as $subnode) {
// get the subnodes parent node's name attribute
$name = $subnode->parentNode->getAttribute('name');
// fetch the first node element with that name attribute
$node = $xpath->query("/nodes/node1[@name='$name']")->item(0);
// move the subnode there
$node->appendChild($subnode);
}
// iterate over all node1 elements that are now empty
foreach($xpath->query('/nodes/node1[not(*)]') as $node) {
// remove them
$node->parentNode->removeChild($node);
}
// print new dom tree
$dom->formatOutput = true;
echo $dom->saveXML();
Note that I am assuming the root node to be <nodes>
. 请注意,我假设根节点是
<nodes>
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.