duandaotuo5542
2011-01-24 21:05
浏览 91

使用XML / Xpath / PHP获取元素名称/值

I have an XML schema that looks as follows:

<xml>
  <user id="1">
    <first_name>Bill</first_name>
    <last_name>Steve</last_name>
    <phone_numbers>
      <work>xxx-xxx-xxxx</work>
      <home>xxx-xxx-xxxx</home>
    </phone_numbers>
   </user>
   <user id="2">
      ........
   </user>
</xml>

Im working on parsing all of this information into PHP using DOM. Ex.

$userInfo = $doc->getElementsByTagName( "user" ); 
foreach($userInfo as $row)
{
       $first_name = $row->getElementsByTagName("first_name");
}

When I try to nest this to select the phone numbers however I get an error. I've tried using XPath to select the phone numbers with equal problems. I tried something along the lines of

$userInfo = $doc->getElementsByTagName( "user" ); 
foreach($userInfo as $row)
{
       $phoneInfo = $row->getElementsByTagName("phone_numbers");
       foreach($phoneInfo as $row2)
       {
            $work = $row2->getElementsByTagName("work");
       }
}

Im curious if Im doing something fundamentally wrong, or how to get this going. I've been tearing my hair out for a few hours now.

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • douhuang3833 2011-01-24 21:30
    已采纳

    You can't get the value directly from a DOMNodeList Object, try this :

    $userInfo = $doc->getElementsByTagName( "user" ); 
    foreach($userInfo as $row)
    {
           $phoneInfo = $row->getElementsByTagName("phone_numbers");
           foreach($phoneInfo as $row2)
           {
                // get the value from the first child
                $work = $row2->getElementsByTagName("work")->item(0)->nodeValue;
                $home = $row2->getElementsByTagName("home")->item(0)->nodeValue;
           }
    }
    
    点赞 评论
  • dsaf415212 2011-01-24 21:19

    Well, you could switch it to SimpleXml which makes this type of parsing easier:

    $userInfo = $doc->getElementsByTagName( "user" ); 
    foreach ($userInfo as $user) {
        $node = simplexml_import_dom($user);
        $id = (string) $node['id'];
        $first = (string) $node->first_name;
        $last = (string) $node->last_name;
        $workPhone = (string) $node->phone_numbers->work;
        $homePhone = (string) $node->phone_numbers->home;
    }
    

    Now, in DomDocument, you could do this by using DomXpath:

    $userInfo = $doc->getElementsByTagName( "user" ); 
    $xpath = new DomXpath($doc);
    foreach ($userInfo as $user) {
        $id = $user->getAttribute('id');
        $first = $xpath->query('//first_name', $user)->item(0)->textContent;
        $last = $xpath->query('//last_name', $user)->item(0)->textContent;
        $work = $xpath->query('//phone_numbers/work', $user)->item(0)->textContent;
        $home = $xpath->query('//phone_numbers/home', $user)->item(0)->textContent;
    }
    

    Note that the above code (both parts) require that the format is exactly that. If you have conditionals, you might want to change it to something like this (the firstname conditional only):

    $userInfo = $doc->getElementsByTagName( "user" ); 
    $xpath = new DomXpath($doc);
    foreach ($userInfo as $user) {
        $id = $user->getAttribute('id');
        $firstQuery = $xpath->query('//first_name', $user);
        if ($firstQuery->length > 0) {
            $first = $firstQuery->item(0)->textContent;
        } else {
            $first = '';
        }
    }
    
    点赞 评论

相关推荐 更多相似问题