PHP-массив доступа в XML

0

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

$feed = 'mydata.xml';
$xml = file_get_contents($feed);
$data = simplexml_load_string($xml);

echo print_r($data);

Результат выглядит так (хотя я многое изрубил):

SimpleXMLElement Object
(
    [merchant] => SimpleXMLElement Object
        (
            [@attributes] => Array
                (
                    [id] => 1
                    [name] => companyname
                )

            [prod] => Array
                (
                    [0] => SimpleXMLElement Object
                         (
                            [@attributes] => Array
                                (
                                     [id] => 690579815
                                     [lang] => en
                                     [pre_order] => no
                                     [web_offer] => yes
                                     [in_stock] => yes
                                )

Мой вопрос: как я могу получить доступ к массиву prod? Я хочу, чтобы это можно было считать так:

count($data['prod']);

А также получить определенные значения полей, но я совершенно новичок в PHP и XML и не могу это сделать.

Благодарю!

  • 2
    $data - это не массив, это экземпляр SimpleXMLElement , используйте его соответственно: $data->merchant->prod[0];
Теги:

3 ответа

0

Мой вопрос: как я могу получить доступ к массиву prod?

Вы не можете. Потому что нет массива. Но все в порядке, спросите вы, просто print_r немного вас обманывает. SimpleXMLElement - это объект, и он может изменить то, что будет показано при получении print_r 'ed, и это подделает вам некоторые массивы.

Некоторые основы для спасения:

$data представляет собой элемент документа XML, который у вас есть. В случае, если вы сомневаетесь в том, что в XML вместо print_r загляните в $data->asXML() (если вы просматриваете источник просмотра браузера или намекаете на вывод как обычный текст, в противном случае браузер скроет все теги).

$data['prod'] дает вам атрибут с именем prod для этого элемента документа. Поскольку его нет, он возвращает null:

var_dump($data['prod']);   ---   NULL

И count NULL равно 0:

var_dump(count(NULL));     ---   int(0)

Вы не хотите заглядывать в элемент документа и не хотите искать атрибуты. Вас интересуют дочерние элементы с именем prod внутри элемента торговца.

Итак, сначала получите первый купеческий элемент:

$merchant = $data->merchant;

Вы получаете элементы с доступом к объекту, то есть с оператором объекта ->.

И получите счетчик числа дочерних элементов с именем prod:

var_dump(count($merchant->prod));   ---   int(3)

Как показано на рисунке, у меня есть три (3) детей с именем prod внутри элемента торговца, представленного $merchant.

Таким образом, вам не нужен массив, SimpleXMLElement позволяет получить доступ ко всем XML-элементам внутри документа XML.

Как было написано ранее, скобки массива используются для доступа к массиву. Таким образом, он выглядит как массив, но на самом деле это объект. Он используется для доступа к атрибутам. Но это верно только в том случае, если ключ не является числом. Если это число, он будет обращаться к n-му именованному элементу:

var_dump($merchant->prod[0]->asXML());

Дает XML первого элемента prod элемента торговца:

string(94) "<prod id="690579815" lang="en" pre_order="no" web_offer="yes" in_stock="yes">product #1</prod>"

Поскольку это первый элемент, вы также можете получить его атрибут id:

var_dump($merchant->prod[0]['id']->asXML());

Что возвращает именно этот атрибут:

string(15) " id="690579815""

Но здесь это не останавливается. Каждый из этих объектов SimpleXMLElement элементов и атрибутов XML можно обвести в строку:

var_dump((string)$merchant->prod[0]);         ---   string(10) "product #1"
var_dump((string)$merchant->prod[0]['id']);   ---   string(9) "690579815"

Чаще всего это фактическая информация, которую вы ищете. Когда вы используете echo или подобное, это строковое кастинг выполняется автоматически btw.

echo $merchant->prod[0]; // prints: "product #1"

Подобно массивам (и объекту), вы также можете перебирать каждый элемент SimpleXMLElement. Например, элемент $merchant:

foreach ($merchant as $children)
{
    echo $children->asXML(), "\n";
}

дает:

<merchant id="1" name="companyname">
        <prod id="690579815" lang="en" pre_order="no" web_offer="yes" in_stock="yes">product #1</prod>
        <prod id="250544605" lang="en" pre_order="no" web_offer="yes" in_stock="yes">product #2</prod>
        <prod id="360355798" lang="en" pre_order="no" web_offer="yes" in_stock="yes">product #3</prod>
</merchant>

Это единственный элемент. Настолько интереснее это с именованными дочерними элементами:

foreach ($merchant->prod as $prod)
{
    echo $prod->asXML(), "\n";
}

Теперь это дает всем детям по имени prod один за другим:

<prod id="690579815" lang="en" pre_order="no" web_offer="yes" in_stock="yes">product #1</prod>
<prod id="250544605" lang="en" pre_order="no" web_offer="yes" in_stock="yes">product #2</prod>
<prod id="360355798" lang="en" pre_order="no" web_offer="yes" in_stock="yes">product #3</prod>

Вы найдете это, как объяснено в Basic SimpleXML, в руководстве по PHP. Проконсультируйтесь с ним как с другим источником.

Просто соблюдайте следующие правила:

  • print_r и var_dump обманывают вас при использовании с SimpleXMLElement
  • Вам не нужен массив, если у вас уже есть SimpleXMLElement
  • В случае, если SimpleXMLElement слишком прост в доступе к данным, его библиотеку сестра DOM можно легко использовать, поскольку вы можете переключиться на нее.

См. Полный пример.

0

Чтобы получить доступ к нему как ассоциативный массив, сделайте следующее:

$data = json_decode(json_encode($data), true);

то вы можете получить к нему доступ так:

count($data['merchant']['prod'])
  • 0
    Я так думаю, так как это больше похоже на массивы, к которым я привык. Как бы я получить доступ к значению 690579815 ?
  • 0
    Вот почему я предложил это. Получите доступ к этому значению с помощью $data['merchant']['prod'][0]['id]
Показать ещё 2 комментария
0

SimpleXMLElement - это объект, поэтому вам также нужно обращаться к ним как к объекту:

print count($data->merchant->prod);

Ещё вопросы

Сообщество Overcoder
Наверх
Меню