У меня есть массив, как 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>
<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>
В основном, C, E и F будут братьями и сестрами, и они будут внутри разделов <comm><name>C/E/F</name></comm>
и тогда внутри этого тега будет D. Каждый элемент должен находиться внутри тэга comm и name.
Я уже сделал код, который выглядит так,
$basecomm = $doc->createElement( "start" );
$doc->appendChild( $basecomm );
$base = $doc->getElementsByTagName("comm");
foreach($ip as $input){
$arr=explode("-",$input);foreach ($arr as $a){
$newcomm=null;
foreach ( $base as $community ) {
foreach($community->childNodes as $nextElement){
if ( $nextElement instanceof DOMElement
&& $nextElement->tagName == 'name' && $nextElement->nodeValue==$a) {
$newcomm = $nextElement->parentNode;
}
}
}
if($newcomm==null){
$newcomm=$doc->createElement("comm");
$xml_comm_name=$doc->createElement("name",htmlspecialchars($a));
$newcomm->appendChild($xml_comm_name);
$basecomm->appendChild($newcomm);
}
$basecomm=$newcomm;
}
}
Моя проблема в том, что весь XML генерируется правильно, но значение D отображается только как дочерний элемент C, а не E и F. Так как я могу исправить свой код, чтобы сделать это? Любая помощь приветствуется. Благодарю.
Ваша проблема в том, что вы не проверяете дочерние элементы в контекст их родителя. Поэтому, когда вы проверяете D
из 'A-B-E-D'
это просто проверка «есть ли D». Это не спрашивает «есть ли D с родителем E». Так что думает, что 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();
Это вывод, который я думаю, что вы после.
<?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>
Других решений пока нет …