【问题标题】:How to remove the [@attributes] in the SimpleXMLElement Object如何删除 SimpleXMLElement 对象中的 [@attributes]
【发布时间】:2014-12-07 20:07:48
【问题描述】:
SimpleXMLElement Object
(
    [@attributes] => Array
        (
            [domain] => http://www.eatingwell.com/category/publication/magazine /september/october_2009
        )

    [0] => September/October 2009
    [1] => American
    [2] => Easy
    [3] => Diabetes appropriate
    [4] => Healthy weight
    [5] => High calcium
    [6] => Low calorie
    [7] => Low cholesterol
    [8] => Bone Health
    [9] => Super Bowl
    [10] => Recipes & Menus - Fresh
    [11] => Recipes & Menus - Vegetarian
    [12] => Cheese
    [13] => Dairy
    [14] => Greens
    [15] => Vegetables
    [16] => Wheat
    [17] => Whole Grains
    [18] => Vegetarian, other
    [19] => Appetizers 
    [20] => Dinner

    [21] => Bake
    [22] => Fall
    [23] => Spring
    [24] => Summer
    [25] => Winter
    [26] => Budget
    [27] => Entertaining, casual 
    [28] => Everyday favorites
    [29] => Quick (total 30 min. or less)
    [30] => Vegetarian
    [31] => Appetizer
    [32] => Main dish, vegetarian
    [33] => Pizza
)

我想从 rss 提要中检索类别,但 $bullet =$item->category;pr($bullet); 它显示上述结果。我只想要数组值 [0] 到 [33]。如何从上述结果中删除@attributes?

【问题讨论】:

    标签: php xml rss simplexml feed


    【解决方案1】:

    尝试:

    unset(xml->attributes()->domain);
    

    【讨论】:

      【解决方案2】:

      我假设 pr() 是一个函数,它出于某种原因只包装了 print_r(),在这种情况下,我会告诉你我用 SimpleXML 问题告诉大家的内容:不要相信 print_r(或 var_dump,或任何正常的调试输出函数)。

      简单的事实是这些属性不存在。 SimpleXML 使用迭代器、魔术方法和其他技巧来提供非常方便的“Do What I mean”接口,但在调试输出中很难总结。

      如果你想遍历所有同名的元素,写foreach ( $item->category as $bullet ),你永远不会发现$bullet被设置为任何属性。不过,它将为每个节点设置一个对象,因此,如果您正在做比echo $bullet 更复杂的事情,您可能希望使用(string)$bullet 提取文本内容。

      如果你确实想获得一个属性,你不会通过查看@attributes 以任何形式找到它,而是通过使用数组样式访问,例如(string)$bullet['domain'].

      将您的代码基于the examples in the manual,而不是调试输出,您会走得更远:)

      【讨论】:

        【解决方案3】:

        根据 IMSoP 的观察,@attributes 不是该对象的真实属性。但是,您可以通过执行以下操作来“作弊”,只要您不再需要将对象作为 SimpleXMLElement 对象进行交互即可:

        <?php
        
        function purgeAttributes( $object ) {
            foreach ( $object as $key => $value ) {
                if ( gettype( $value ) == 'object' ) {
                    $object->$key = purgeAttributes( $value );
                }
        
                if ( $key == '@attributes' ) {
                    unset( $object->$key );
                }
            }
        
            return $object;
        }
        
        $x = SimpleXML_load_string('<foo bar="baz" />');
        
        $x = json_decode( json_encode( $x ) );
        
        $x = purgeAttributes( $x );
        
        var_dump( $x );
        

        【讨论】:

        • 这行不通(自己测试:3v4l.org/a6MFh)也不会有类似的东西,因为该属性实际上并不存在,它只是 print_r 尝试向您显示 XML 节点包含的内容的方式.
        • 好的,当然,您可以将有用的对象变成无用的 stdClass,然后对其进行操作。聪明,如果相当无意义恕我直言:问题的前提是您犯的同一个错误,即属性将像普通属性一样显示。您可能应该使用工作代码编辑您的答案。
        【解决方案4】:

        我做了这个,似乎有效。编码->解码应该足以将 SimpleXMLElement 对象转换为 StdClass 对象并按照您想要的方式操作:

        公共函数 cleanXML($xmlString) {

            $xmlString = str_replace(array("\n", "\r", "\t"), '', $xmlString);
            $xmlString = trim(str_replace('"', "'", $xmlString));
            $object = SimpleXML_load_string($xmlString);
            $object = json_decode( json_encode( $object ) );
            foreach ( $object as $key => $value ) {
                if ( $key == '@attributes' ) {
                    unset( $object->$key );
                }
            }
            return $object;
        }
        

        【讨论】:

        • 正如我在另一个答案下面所说,没有理由这样做。像这样转换为stdClass 对象只是丢弃了SimpleXML 的所有功能,而在你这样做时丢弃了@attributes 属性丢弃了你正在处理的部分XML 。老实说,只需使用the really simple facilities SimpleXML provides 提取您需要的数据,而不是像这样使用字符串替换和通用伪对象进行破解。
        猜你喜欢
        • 2017-02-14
        • 2012-08-27
        • 2011-11-23
        • 2012-03-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-04
        • 2021-07-04
        相关资源
        最近更新 更多