Обнаружение свойства массива simpleXml

Я думаю, что здесь мне не хватает чего-то действительно очевидного, но может ли кто-нибудь объяснить мне, почему я получаю результат, который я получаю, а не результат, который я ожидаю от следующих дампов var:

Вот исходный xml:

<result>
    <category>
        <id>3</id>
        <name>Category 1</name>
        <subcategory>
            <id>9</id>
            <name>SubCat 1</name>
        </subcategory>
        <subcategory>
            <id>10</id>
            <name>SubCat 2</name>
        </subcategory>
        <subcategory>
            <id>11</id>
            <name>SubCat 3</name>
        </subcategory>
    </category>
</result>

Что я делаю:

$xml = new SimpleXMLElement($file);
foreach($xml->category as $node)
{
    echo "dump 1:
";
    var_dump($node);
    echo "**********************************************
dump 2:
";
    var_dump($node->subcategory);
    die();
}

Это выводит:

dump 1:
object(SimpleXMLElement)#130 (3) {
    ["id"]=>
    string(1) "3"
    ["name"]=>
    string(10) "Category 1"
    ["subcategory"]=>
    array(3) {
        [0]=>
        object(SimpleXMLElement)#133 (2) {
            ["id"]=>
            string(1) "9"
            ["name"]=>
            string(8) "SubCat 1"
        }
        [1]=>
        object(SimpleXMLElement)#135 (2) {
            ["id"]=>
            string(2) "10"
            ["name"]=>
            string(8) "SubCat 2"
        }
        [2]=>
        object(SimpleXMLElement)#136 (2) {
            ["id"]=>
            string(2) "11"
            ["name"]=>
            string(8) "SubCat 3"
        }
    }
}
**********************************************
dump 2:
object(SimpleXMLElement)#138 (2) {
    ["id"]=>
    string(1) "9"
    ["name"]=>
    string(8) "SubCat 1"
}

Первый дамп var выводит то, что я ожидал, но вывод, который я ожидал бы для второго var_dump, был бы:

array(3) {
    [0]=>
    object(SimpleXMLElement)#133 (2) {
        ["id"]=>
        string(1) "9"
        ["name"]=>
        string(8) "SubCat 1"
    }
    [1]=>
    object(SimpleXMLElement)#135 (2) {
        ["id"]=>
        string(2) "10"
        ["name"]=>
        string(8) "SubCat 2"
    }
    [2]=>
    object(SimpleXMLElement)#136 (2) {
        ["id"]=>
        string(2) "11"
        ["name"]=>
        string(8) "SubCat 3"
    }
}

Или даже объект, содержащий все элементы массива. Почему это не так?

Я вижу, что когда я вызываю var_dump($node->subcategory), он сбрасывает первый найденный узел «подкатегории», но почему тогда он приводит все узлы «подкатегории» к массиву для первого дампа var, но не для второго? И как мне имитировать это поведение, чтобы определить, содержит ли «подкатегория» более одного объекта (как это происходит в первом дампе var)?

В основном то, что я пытаюсь сделать, это определить, содержит ли свойство SimpleXMLElement массив дополнительных значений (т.е. если оно содержит дочерние узлы)

Я пробовал все виды, но не могу определить, содержит ли одно из свойств объекта simpleXml набор массивов.

Обновление:

Я нашел это работает:

if(count($node->subcategory)>1)
{
    // we have  more than one subcategory
}

Но это не самый элегантный способ, я уверен, что должен быть более чистый метод?


person Stu    schedule 03.10.2012    source источник
comment
ответ на этот пост может помочь вам: stackoverflow.com/questions/2751711/ var_dump($node[subcategoy]);   -  person feskr    schedule 03.10.2012
comment
@feskr спасибо, я проталкиваю все свойства (и, следовательно, атрибуты) через цикл foreach в моем реальном коде, и похоже, что атрибуты и свойства не различаются, что является проблемой!   -  person Stu    schedule 03.10.2012
comment
@feskr var_dump($node["subcategory"]) выводит: NULL   -  person Stu    schedule 03.10.2012
comment
извините, у меня есть еще один для вас в ответ   -  person feskr    schedule 03.10.2012


Ответы (2)


Это свойство является объектом итератора:

$node->subcategory

И если вам нужно получить все предметы, попробуйте:

foreach($xml->category as $node)
{
...
  foreach($node->subcategory as $subcategory)
  {
     $data[] = (array) $subcategory
  }
...
}

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

И вы можете использовать xpath, если не измените XML-дерево:

$categories = $xml->xpath('/category/subcategory');
var_dump($categories)
person Yegor Lukash    schedule 03.10.2012
comment
метод xpath не будет работать в моем конкретном сценарии, поскольку подкатегории могут быть рекурсивными (кошмар!). Тем не менее, метод $data прекрасно адаптируется, спасибо! - person Stu; 03.10.2012

Настройте свой xml-файл:

<result>
    <category>
        <id>3</id>
        <name>Category 1</name>
        <subcategories>
          <subcategory>
            <id>9</id>
            <name>SubCat 1</name>
          </subcategory>
          <subcategory>
            <id>10</id>
            <name>SubCat 2</name>
          </subcategory>
          <subcategory>
            <id>11</id>
            <name>SubCat 3</name>
          </subcategory>
        </subcategories>
    </category>
</result>

И попытаться:

var_dump($node->subcategories);
person feskr    schedule 03.10.2012
comment
Спасибо, это сработает, только я, к сожалению, не могу изменить файл XML! - person Stu; 03.10.2012