Исчезающие атрибуты в PHP SimpleXML Object? - PullRequest
7 голосов
/ 19 декабря 2011

Мне нужно вернуть объект SimpleXML, преобразованный как объект JSON, для работы с ним в JavaScript.Проблема заключается в том, что ни у одного объекта со значением нет атрибутов.

Например:

<customer editable="true" maxChars="9" valueType="numeric">69236</customer>

становится в объекте SimpleXML:

"customer":"69236"

Гдетакое @attributes объект?

Ответы [ 4 ]

8 голосов
/ 30 марта 2012

Это сводило меня с ума несколько раз.Когда SimpleXML встречает узел, который имеет только текстовое значение, он удаляет все атрибуты.Мой обходной путь состоял в том, чтобы изменить XML перед синтаксическим анализом с SimpleXML.С помощью небольшого количества регулярных выражений вы можете создать дочерний узел, который содержит фактическое текстовое значение.Например, в вашей ситуации вы можете изменить XML на:

<customer editable="true" maxChars="9" valueType="numeric"><value>69236<value></customer>

Некоторые примеры кода, предполагающие, что ваша строка XML была в $ str:

$str = preg_replace('/<customer ([^>]*)>([^<>]*)<\/customer>/i', '<customer $1><value>$2</value></customer>', $str);
$xml = @simplexml_load_string($str);

Это сохранит атрибутывложить текстовое значение в дочерний узел.

5 голосов
/ 27 октября 2015

Я понимаю, что это старый пост, но в случае, если он окажется полезным.Ниже приводится расширение решения @ ryanmcdonnell для работы с любыми тегами вместо жестко закодированных тегов.Надеюсь, это кому-нибудь поможет.

$str = preg_replace('/<([^ ]+) ([^>]*)>([^<>]*)<\/\\1>/i', '<$1 $2><value>$3</value></$1>', $result);

Основным отличием является то, что он заменяет /<customer на /<([^ ]+), а затем </customer> на </\\1>

, что говорит ему о соответствии этой части поиска спервый элемент в шаблоне.

Затем он просто настраивает заполнители ($1, $2, $3), чтобы учесть тот факт, что теперь есть три под-совпадения вместо двух.

0 голосов
/ 24 августа 2016

Это старый вопрос, но я нашел что-то, что работает аккуратно - разобрать его в объект DOMNode.

// $customer contains the SimpleXMLElement
$customerDom = dom_import_simplexml($customer);
var_dump($customerDom->getAttribute('numeric'));

Покажет:

string 'numeric'
0 голосов
/ 20 декабря 2011

Вот некоторый код для перебора атрибутов и создания JSON. Если поддерживает, один или несколько клиентов.

Если ваш XML выглядит так (или только один клиент)

<xml>
<customer editable="true" maxChars="9" valueType="numeric">69236</customer>
<customer editable="true" maxChars="9" valueType="numeric">12345</customer>
<customer editable="true" maxChars="9" valueType="numeric">67890</customer>
</xml>

Итерируйте это так.

try {
    $xml = simplexml_load_file( "customer.xml" );

    // Find the customer
    $result = $xml->xpath('/xml/customer');

    $bFirstElement = true;
    echo     "var customers  = {\r\n";
    while(list( , $node) = each($result)) {
        if( $bFirstElement ) {
            echo "'". $node."':{\r\n";
            $bFirstElement = false;
        } else {
            echo ",\r\n'". $node."':{\r\n";
        }

        $bFirstAtt = true;
        foreach($node->attributes() as $a => $b) { 
            if( $bFirstAtt ) {
                echo "\t".$a.":'".$b."'";
                $bFirstAtt = false;
            } else {
                echo ",\r\n\t".$a.":'".$b."'";
            }
        }
        echo "}";
    }
    echo "\r\n};\r\n";
} catch( Exception $e ) {
    echo "Exception on line ".$e->getLine()." of file ".$e->getFile()." : ".$e->getMessage()."<br/>";
}

Для создания такой структуры JSON

var customers  = {
'69236':{
    editable:'true',
    maxChars:'9',
    valueType:'numeric'},
'12345':{
    editable:'true',
    maxChars:'9',
    valueType:'numeric'},
'67890':{
    editable:'true',
    maxChars:'9',
    valueType:'numeric'}
};

Наконец, в вашем скрипте, доступ к атрибуту, как это

WScript.Echo( customers["12345"].editable );

Удачи

...