Как решить проблему многоуровневого XML с помощью Dom Document в PHP?

У меня есть массив, как 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. Так как я могу исправить свой код, чтобы сделать это? Любая помощь приветствуется. Благодарю.

0

Решение

Ваша проблема в том, что вы не проверяете дочерние элементы в контекст их родителя. Поэтому, когда вы проверяете 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>
1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector