Получение имен / значений элементов с помощью XML / Xpath / PHP - PullRequest
3 голосов
/ 25 января 2011

У меня есть XML-схема, которая выглядит следующим образом:

<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>

Я работаю над анализом всей этой информации в PHP с использованием DOM.Пример.

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

Когда я пытаюсь вложить это, чтобы выбрать номера телефонов, я получаю сообщение об ошибке.Я пытался использовать XPath для выбора телефонных номеров с одинаковыми проблемами.Я попробовал что-то вроде

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

Мне любопытно, если я делаю что-то в корне неправильно, или как это сделать.Я рвал на себе волосы уже несколько часов.

Ответы [ 2 ]

3 голосов
/ 25 января 2011

Вы не можете получить значение напрямую из объекта DOMNodeList, попробуйте это:

$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;
       }
}
1 голос
/ 25 января 2011

Ну, вы можете переключить его на SimpleXml , что облегчает этот тип анализа:

$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;
}

Теперь, в DomDocument, вы можете сделать это, используя 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;
}

Обратите внимание, что приведенный выше код (обе части) требует, чтобы формат был именно таким.Если у вас есть условные выражения, вы можете изменить их на что-то вроде этого (только условное firstname):

$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 = '';
    }
}
...