SimpleXml属性不显示没有子元素的元素

时间:2013-10-17 09:21:51

标签: php simplexml

我有以下XML:

<?xml version="1.0"?>
<STATUS_LIST>
    <ORDER_STATUS SORDER_CODE="SO001" ASSOCIATED_REF="001">
        <INVOICES>
            <INVOICE INVOICE_CODE="???">SOMETHING</INVOICE>
        </INVOICES>
    </ORDER_STATUS>
</STATUS_LIST>

当我运行以下代码时:

$statuses = simplexml_load_string($result); //Where $result is my XML

if (!empty($statuses))
{
    foreach ($statuses as $status)
    {
        foreach ($status->INVOICES as $invoice)
        {
            echo (string)$invoice->attributes()->INVOICE_CODE;   
        }
    }
}

我单步执行此代码,可以查看针对ORDER_STATUS的属性,但我无法查看针对INVOICE的属性。但是,我可以看到SOMETHING对发票的价值。

知道可能导致这种情况的原因吗?

更新

经过一些测试后,我可以获取属性来显示我是否在INVOICE元素中添加了一个元素,所以如果我使用这个xml,它将起作用:

<?xml version="1.0"?>
<STATUS_LIST>
    <ORDER_STATUS SORDER_CODE="SO001" ASSOCIATED_REF="001">
        <INVOICES>
            <INVOICE INVOICE_CODE="???"><TEST>tester</TEST></INVOICE>
        </INVOICES>
    </ORDER_STATUS>
</STATUS_LIST>

所以在里面有一个元素来获取属性!?

2 个答案:

答案 0 :(得分:1)

根据this past question,“SimpleXML不允许同一元素上的属性和文本。”这太荒谬了,我找不到任何关于这个事实的官方报道,但似乎是真的。瘸。它是有效的XML。我知道Perl SimpleXML读得很好。

答案 1 :(得分:1)

你的问题与没有内容的元素无关,你只是简单地定义了你的循环。

当您编写foreach ($status->INVOICES as $invoice)时,SimpleXML将循环遍历$status元素的每个子元素,该元素称为INVOICES;在这种情况下,总会有一个这样的元素。但你真正想要的是遍历该元素的所有孩子 - 单个INVOICE节点。

为此,您可以使用以下方法之一:

  • foreach ($status->INVOICES->children() as $invoice)(循环遍历第一个子节点,仅在这种情况下为INVOICES元素)
  • foreach ($status->INVOICES[0]->children() as $invoice)(同样,但更明确地选择第一个INVOICES节点)
  • foreach ($status->INVOICES[0] as $invoice)(实际上再次相同:因为你专门选择了一个节点,然后要求一个循环,SimpleXML假设你想要它的子节点;这就是foreach($statuses as $status)作为外部工作的原因环)
  • foreach ($status->INVOICES->INVOICE as $invoice)(仅覆盖名为INVOICE的子节点,恰好是所有这些节点)

就个人而言,我会重写你的样本循环,如下所示:

foreach ($statuses->ORDER_STATUS as $status)
{
    foreach ($status->INVOICES->INVOICE as $invoice)
    {
        echo (string)$invoice['INVOICE_CODE'];   
    }
}

Here's a live demo to prove that that works.