简体   繁体   中英

PHP XML DOM - Distinguishing nodes based on parent attributes/elements

First of all, thanks for the time reading this :)

I need help reordering an XML feed. I've tried many things and researched, but can't come up with a solution.

<xml>
<group>
   <result>
      <title>Title</title>
      <url>URL</url>
      <text>Text</text>
   </result>
   <result>
      <title>Title</title>
      <url>URL</url>
      <text>Text</text>
   </result>
</group>
<group region=top>
   <result>
      <title>Title</title>
      <url>URL</url>
      <text>Text</text>
   </result>
</group>
<group type=bottom>
   <result>
      <title>Title</title>
      <url>URL</url>
      <text>Text</text>
      <moreinfo>
             <result>
             <title>Title</title>
             </result>
             <result>
             <title>Title</title>
             </result>
      </moreinfo>
   </result>
</group>
</xml>

What I am trying to do is re-order the XML feed to display each node inside 'result'. However, I need the feed reordered so the 'result' from 'group region=top' is at the top, then the results from 'group', then results from 'group region=bottom'.

You might notice there is another 'result' tag nested inside of a 'result' tag in 'group region=bottom', which is causing most of the issues. The way I envision a solution to this is with the following pseudo-code:

$books = $doc->getElementsByTagName( "result" );

    foreach( $books as $book )
    {           
    if (parent_attribute = top){    

        $toptitle = $book->getElementsByTagName( "title" );
        $toptitle = $toptitle->item(0)->nodeValue;

            $topnew[]  =array("title"=>$toptitle);  
       }

            if (parent_attribute = null){

            $middletitle = $book->getElementsByTagName( "title" );
        $middletitle = $middletitle->item(0)->nodeValue;

            $middlenew[]  =array("title"=>$middletitle);            

        }

            if (parent_attribute = bottom){

            $bottomtitle = $book->getElementsByTagName( "title" );
        $bottomtitle = $bottomtitle->item(0)->nodeValue;

                if (parent_element = moreinfo){

                $moretitle = $book->getElementsByTagName( "title" );
                $moretitle = $moretitle->item(0)->nodeValue;
                }
            $bottomnew[]  =array("title"=>$bottomtitle, "more"=>$moretitle);
        } 

}

The XML you posted is invalid and not consistent, as attribute values have to be enclosed in "" , for consistency see my comment above.

Here's how I do it using simplexml and xpath , it can be easily adapted to DOM as well.

$xml = simplexml_load_string($x); // assuming XML in $x

$regions['top'] = $xml->xpath("group[@region='top']/result");
$regions['middle'] = $xml->xpath("group[not(@*)]/result"); // <group> with no attribute
$regions['bottom'] = $xml->xpath("group[@region='bottom']/result");

// output:
foreach ($regions as $region => $results) {

    echo "$region:<br />";
    foreach ($results as $result) {
    echo $result->title . "<br />";
    if (count($result->moreinfo) > 0)
        foreach ($result->moreinfo->result as $subresult) 
                    echo "____$subresult->title<br />";
    } // foreach $results
} // foreach $regions

see it working: http://codepad.viper-7.com/5adWxC

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM