我必须使用DOM
操作XML文件这是我的情况:
<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>
我希望将所有节点分组读取<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>
用dom做这种操作的php代码是什么?有可能吗?
答案 0 :(得分:1)
您可以这样做(请确保您的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;
}
}
答案 1 :(得分:1)
您可以使用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
}
}
您可以在http://www.zorba-xquery.com/html/demo#TuRqsG1GZewGQD3f0QhmsIpVmTc=现场试用该示例 有关如何在PHP上安装XQuery扩展的说明,请访问http://www.zorba-xquery.com/html/entry/2011/12/27/PHP_Meets_XQuery
答案 2 :(得分:0)
假设$xml
拥有您的XML字符串(demo):
$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();
请注意,我假设根节点为<nodes>
。