如何在PHP中使用Dom文档解决多层XML问题?
我有一个像ip=[“A-B-C-D”,“A-B-E-D”,“A-B-F-D”]这样的数组。现在我必须基于这个层次结构创建一个XML。XML的预期输出将为如何在PHP中使用Dom文档解决多层XML问题?,php,arrays,xml,dom,Php,Arrays,Xml,Dom,我有一个像ip=[“A-B-C-D”,“A-B-E-D”,“A-B-F-D”]这样的数组。现在我必须基于这个层次结构创建一个XML。XML的预期输出将为 <start> <comm> <name>A</name> <comm> <name>B</name> <comm> <name>C</name>
<start>
<comm>
<name>A</name>
<comm>
<name>B</name>
<comm>
<name>C</name>
<comm>
<name>D</name>
</comm>
</comm>
<comm>
<name>E</name>
<comm>
<name>D</name>
</comm>
</comm>
<comm>
<name>F</name>
<comm>
<name>D</name>
</comm>
</comm>
</comm>
</comm>
我的问题是,整个XML都在正确生成,但值D只显示为C的子项,而不是E和F的子项。因此,如何修复代码来实现这一点?感谢您的帮助。谢谢。您的问题是您没有在父元素的上下文中检查子元素。因此,当你检查
'A-B-E-D'
的D
时,它只是在检查“是否有D”。它不是问“父母E是否有D”。所以它认为D已经存在了
如果每次从树的顶部开始时都将有效元素集重置为正确的父元素,则应该会得到正确的结果
<?php
$ip=["A-B-C-D","A-B-E-D","A-B-F-D","G-H","G-B","X-Y-G-B"];
$doc = new DOMDocument();
$doc->preserveWhiteSpace = false;
$doc->formatOutput = true;
$basecomm = $doc->createElement( "start" );
$doc->appendChild( $basecomm );
foreach($ip as $input){
$base = $doc->getElementsByTagName("comm");
$currentcomm = $basecomm;
$arr = explode("-", $input);
foreach ($arr as $k => $a) {
$parentComm = null;
foreach ( $base as $x => $community ) {
foreach ($community->childNodes as $nextElement) {
if ($nextElement->tagName == 'name' && $nextElement->nodeValue==$a) {
$parentComm = $nextElement->parentNode;
}
}
}
if ($parentComm==null){
$newcomm=$doc->createElement("comm");
$xml_comm_name=$doc->createElement("name",htmlspecialchars($a));
$newcomm->appendChild($xml_comm_name);
$currentcomm->appendChild($newcomm);
$base = $newcomm->getElementsByTagName("comm");
$currentcomm = $newcomm;
} else {
$base = $parentComm->getElementsByTagName("comm");
$currentcomm = $parentComm;
}
}
}
echo $doc->saveXML();
createElement(“名称”,htmlspecialchars($a));
$newcomm->appendChild($xml\u comm\u name);
$currentcomm->appendChild($newcomm);
$base=$newcommm->getElementsByTagName(“comm”);
$currentcomm=$newcomm;
}否则{
$base=$parentComm->getElementsByTagName(“comm”);
$currentcomm=$parentComm;
}
}
}
echo$doc->saveXML();
这是输出,我想这是你想要的
<?xml version="1.0"?>
<start>
<comm>
<name>A</name>
<comm>
<name>B</name>
<comm>
<name>C</name>
<comm>
<name>D</name>
</comm>
</comm>
<comm>
<name>E</name>
<comm>
<name>D</name>
</comm>
</comm>
<comm>
<name>F</name>
<comm>
<name>D</name>
</comm>
</comm>
</comm>
</comm>
<comm>
<name>G</name>
<comm>
<name>H</name>
</comm>
<comm>
<name>B</name>
</comm>
</comm>
<comm>
<name>X</name>
<comm>
<name>Y</name>
<comm>
<name>G</name>
<comm>
<name>B</name>
</comm>
</comm>
</comm>
</comm>
</start>
A.
B
C
D
E
D
F
D
G
H
B
X
Y
G
B
您已经问过发生了什么变化?@u\u mulder上一个问题,因为我想知道在构建层次结构时如何命名节点。在这里,我只处理节点内的值,而标记名保持不变。嗨,如果我添加另一个数组元素,如“G-H”,这就不起作用了。那么作为输出给出的结构是不正确的。这是因为您正在用新的基址覆盖$basecomm
。如果您将$basecomm
保持原样,并使用$currentcomm
替代它,事情应该是正确的。请参阅更新。好的,但这又回到了我的第一个问题,即如果数组元素是重复的,那么它没有添加到正确的位置。如果最后一个数组元素是“G-B”而不是“G-H”,那么B也不会被添加到G中。基本上,您需要将两者结合起来。首先,在其父节点的上下文中检查当前节点。C-D和E-D是不同的Ds。第二,不要覆盖基本节点,但要跟踪您正在处理的树的当前部分。如果您可以更新代码(如果可能的话),这将对我和其他阅读此答案的人有所帮助。谢谢你的帮助。
<?xml version="1.0"?>
<start>
<comm>
<name>A</name>
<comm>
<name>B</name>
<comm>
<name>C</name>
<comm>
<name>D</name>
</comm>
</comm>
<comm>
<name>E</name>
<comm>
<name>D</name>
</comm>
</comm>
<comm>
<name>F</name>
<comm>
<name>D</name>
</comm>
</comm>
</comm>
</comm>
<comm>
<name>G</name>
<comm>
<name>H</name>
</comm>
<comm>
<name>B</name>
</comm>
</comm>
<comm>
<name>X</name>
<comm>
<name>Y</name>
<comm>
<name>G</name>
<comm>
<name>B</name>
</comm>
</comm>
</comm>
</comm>
</start>