PHP SimpleXML 对象中的属性消失?

Posted

技术标签:

【中文标题】PHP SimpleXML 对象中的属性消失?【英文标题】:Disappearing attributes in PHP SimpleXML Object? 【发布时间】:2012-01-23 16:28:00 【问题描述】:

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

举个例子:

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

成为 SimpleXML 对象:

"customer":"69236"

@attributes 对象在哪里?

【问题讨论】:

【参考方案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 );

祝你好运

【讨论】:

【参考方案2】:

这让我好几次发疯了。当 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);

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

【讨论】:

如果元素中有例如 CDATA 块,则会失败,如下所示: 对我来说,解决方案是在循环 xml 对象时显式调用 -&gt;children()。如果我不这样做,属性就消失了。【参考方案3】:

我知道这是一篇旧帖子,但以防万一它被证明有用。下面扩展了@ryanmcdonnell 的解决方案以处理任何标签而不是硬编码标签。希望它可以帮助某人。

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

主要区别在于它将/&lt;customer替换为/&lt;([^ ]+),然后将&lt;/customer&gt;替换为&lt;/\\1&gt;

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

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

【讨论】:

如果元素中有例如 CDATA 块,这也会失败,如下所示:【参考方案4】:

这是一个老问题,但我发现了一些很好的方法 - 将其解析为 DOMNode 对象。

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

将显示:

string 'numeric'

【讨论】:

【参考方案5】:

看来这是bug 并且在php 7.4.5 中已修复。

【讨论】:

以上是关于PHP SimpleXML 对象中的属性消失?的主要内容,如果未能解决你的问题,请参考以下文章

PHP 5 SimpleXML 函数

PHP SimpleXML 不保留 XML 属性中的换行符

PHP SimpleXML:提要修改

simpleXML技术解析xml文件(php)

PHP SimpleXML + 获取属性

PHP SimpleXML解析具有多个属性的元素