如何在PHP中使用Dom Document解决多级XML的问题?

时间:2017-09-12 08:48:04

标签: 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>
            <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和名称标签内。< / p>

我已经完成了这样的代码,

$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.那么如何修复我的代码呢?任何帮助表示赞赏。感谢。

1 个答案:

答案 0 :(得分:1)

您的问题是您没有检查其父级上下文中的子元素。因此,当您检查D的{​​{1}}时,它只是检查“是否存在D”。它不是在问“父母E是否有D”。所以它认为D已经存在。

如果您重置有效元素集以在每次从树顶部开始时检查正确的父元素,您应该得到正确的结果。

'A-B-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();