dongyigua4468 2013-10-17 09:21
浏览 24
已采纳

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

I have the following 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>

When I run the following code:

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

I step through this code and I can see the attributes against ORDER_STATUS but I can't see the attributes against INVOICE. I can however see the value SOMETHING against invoice.

Any idea what could cause this?

Update

After some testing, I can get the attributes to show if I add an element into the INVOICE element, so if I use this xml instead it will work:

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

So it has to have an element inside to pick up the attributes!?

  • 写回答

2条回答 默认 最新

  • doucuo8618 2013-10-19 21:32
    关注

    Your problem has nothing to do with the element having no content, you simply have your loops defined slightly wrong.

    When you write foreach ($status->INVOICES as $invoice), SimpleXML will loop over every child of the $status element which is called INVOICES; in this case there will always be exactly one such element. But what you actually wanted is to loop over all the children of that element - the individual INVOICE nodes.

    To do that you can use one of the following:

    • foreach ($status->INVOICES->children() as $invoice) (loop over all child nodes of the first, and in this case only, INVOICES element)
    • foreach ($status->INVOICES[0]->children() as $invoice) (the same, but being more explicit about selecting the first INVOICES node)
    • foreach ($status->INVOICES[0] as $invoice) (actually does the same again: because you've specifically selected one node, and then asked for a loop, SimpleXML assumes you want its children; this is why foreach($statuses as $status) works as the outer loop)
    • foreach ($status->INVOICES->INVOICE as $invoice) (loop over only child nodes called INVOICE, which happens to be all of them)

    Personally, I would rewrite your sample loop as below:

    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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 unity第一人称射击小游戏,有demo,在原脚本的基础上进行修改以达到要求
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染