PHP SimpleXML对象中消失的属性?

时间:2011-12-19 14:53:37

标签: php xml json object simplexml

我需要返回一个转换为JSON对象的SimpleXML对象,以便在JavaScript中使用它。问题是任何具有值的对象都没有属性。

举个例子:

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

成为SimpleXML对象:

"customer":"69236"

@attributes对象在哪里?

5 个答案:

答案 0 :(得分:8)

这让我多次疯狂。当SimpleXML遇到只有文本值的节点时,它会删除所有属性。我的解决方法是在使用SimpleXML解析之前修改XML。使用一些正则表达式,您可以创建包含实际文本值的子节点。例如,在您的情况下,您可以将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);

这将保留属性并将文本值嵌套在子节点中。

答案 1 :(得分:5)

我意识到这是一个老帖子,但万一它证明有用。以下扩展@ ryanmcdonnell的解决方案,适用于任何标签而不是硬编码标签。希望它可以帮助某人。

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

主要的不同之处在于它将/<customer替换为/<([^ ]+),然后将</customer>替换为</\\1>

告诉它将搜索的那一部分与模式中的第一个元素相匹配。

然后它只是调整占位符($1$2$3)以说明现在有三个子匹配而不是两个。

答案 2 :(得分:1)

因此,这似乎是bug,并已在PHP 7.4.5中修复。

答案 3 :(得分:0)

这是一个老问题,但我找到了一些工作正常的东西 - 将其解析为DOMNode对象。

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

将显示:

string 'numeric'

答案 4 :(得分:-1)

这里有一些代码来迭代属性,并构造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 );
祝你好运