php 正在检测simpleXml数组属性

bgibtngc  于 2023-03-07  发布在  PHP
关注(0)|答案(4)|浏览(118)

我想我错过了一些非常明显的东西,但是有人能解释一下为什么我在下面的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_dump的输出是我所期望的,但是第二个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)时,它会转储它找到的第一个'subcategory'节点,但是为什么它会在第一个var转储中将所有'subcategory'节点转换为一个数组,而在第二个var转储中却没有呢?我如何模仿这个行为来检测'subcategory'是否包含多个对象(就像它在第一个var转储中所做的那样)?
基本上,我尝试做的是检测SimpleXMLElement的属性是否包含更多值的数组(即,它是否包含子节点)
我尝试了各种方法,但似乎无法检测simpleXml对象的属性之一是否包含数组集。

    • 更新日期:**

我发现这很管用:

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

但这不是最优雅的方式,我相信一定有一个更干净的方法?

yhuiod9q

yhuiod9q1#

此属性是迭代器的对象:

$node->subcategory

如果您需要获取所有项目,请尝试:

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

如果你需要知道你成功地使用计数方法的子类别项目计数。
如果不更改XML树,则可以使用xpath:

$categories = $xml->xpath('/category/subcategory');
var_dump($categories)
3vpjnl9f

3vpjnl9f2#

调整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);
w6lpcovy

w6lpcovy3#

我认为主要的观点是由Yegor Lukash指出的,他说这是一个迭代器。
但是,您可以通过以下方式获得预期结果:

foreach($xml->category as $node)
{
    $subcategories = ((array)$node)['subcategory'];   
    var_dump($subcategories);
}

关于feskr的答案,我认为获得更清晰的xml代码会很有用,在这种情况下,我的解决方案将变成:

foreach($xml->category as $node)
{
    $subcategories = ((array)$node->subcategories)['subcategory'];
    var_dump($subcategories);
}

但在这种情况下,这将是更好的:

foreach($xml->category as $node)
{
    foreach($node->subcategories->children() as $subcategory) {
      var_dump($subcategory);
    }
}
hvvq6cgz

hvvq6cgz4#

(因为XML给我带来了很多麻烦,所以我改用“给予me a associative array”,方法是使用
$myarray = json_decode(json_encode(simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
这样,“CDATA[”部分也将作为明文包括在内
问候

相关问题