SimpleXMLElement foreach child Array/Value

SimpleXMLElement foreach child Array/Value

我有以下有效的代码,但似乎是错误的实现方式。忽略“....”,这是我们不需要关心的所有额外内容。我遇到的问题是 Sup 有时是一个数组,有时它只是一个值(或者 print_r 声称,我 thought/hoped 它只是一个值元素数组)。

$users 是一个简单的 XMLElement。

foreach($users as $user) {
    if ($user->InstSup->Sup[1] == '') {
        foreach($user->InstSup as $affid) {
        ....
    } else {
        foreach($user->InstSup->Sup as $affid) {

以下是不同的实例...

<Users>
    <User>
        <InstSup><Sup>1</Sup></InstSup>
    </User>
    <User>
        <InstSup><Sup>2</Sup><Sup>3</Sup><Sup>4</Sup><Sup>5</Sup></InstSup>
    </User>
</Users>

谢谢。

首先,当你处理SimpleXMLElement时,不要相信print_r(或var_dump)的输出秒。它没有显示全貌,最好按原样查看 XML,例如 asXML() method.

现在解决您遇到的问题。当您只想获得属于 <InstSup><Sup> 元素的列表(可以说是 "array")时,您最好使用 Xpath。它相当简单,可以为您提供所需的数组:

$users = new SimpleXMLElement($buffer);
$sups  = $users->xpath('/Users/User/InstSup/Sup');
foreach ($sups as $index => $sup) {
    printf("#%d: %s (%s)\n", $index, $sup, $sup->asXML());
}

这将创建以下输出:

#0: 1 (<Sup>1</Sup>)
#1: 2 (<Sup>2</Sup>)
#2: 3 (<Sup>3</Sup>)
#3: 4 (<Sup>4</Sup>)
#4: 5 (<Sup>5</Sup>)

这是 $buffer 完成示例:

$buffer = <<<XML
<Users>
    <User>
        <InstSup><Sup>1</Sup></InstSup>
    </User>
    <User>
        <InstSup><Sup>2</Sup><Sup>3</Sup><Sup>4</Sup><Sup>5</Sup></InstSup>
    </User>
</Users>
XML;

如输出中的排列所示,即使 <Sup> 元素位于(同名但)不同的父元素内,XPath 查询表达式

/Users/User/InstSup/Sup

returns 文档中该路径中的所有元素。

所以希望你现在能更好地理解 print_r 不仅没有那么有用,因为它没有显示全貌,而且通过了解文档如何对节点进行排序,你甚至可以使用 Xpath 表达式更容易查询数据。