每个子数组/值的SimpleXMLElement


SimpleXMLElement foreach child Array/Value

我有以下代码,它可以工作,但似乎是不正确的实现方式。忽略"…",这都是我们不需要关心的额外东西。我遇到的问题是,Sup有时是一个数组,而其他时候它只是一个值(或者print_r声称的那样,我认为/希望它只是一元素数组)。

$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>

谢谢。

首先,在处理SimpleXMLElements时,不要相信print_r(或var_dump)的输出。它并没有显示全貌,最好按原样查看XML,例如使用asXML()方法。

现在来谈谈你遇到的问题。当您只想拥有<InstSup>的子级<Sup>元素的列表(可以说是"数组")时,最好使用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

从文档中返回该路径中的所有元素。

因此,希望您现在能更好地理解print_r不仅没有那么有用,因为它没有显示全貌,而且通过了解文档中节点的排列方式,您可以更容易地使用Xpath表达式查询数据。