如何在PHP中使用Dom文档解决多层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>

我有一个像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>

我的问题是,整个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>