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 javaweb项目无法正常跳转
  • ¥15 VMBox虚拟机无法访问
  • ¥15 skd显示找不到头文件
  • ¥15 机器视觉中图片中长度与真实长度的关系
  • ¥15 fastreport table 怎么只让每页的最下面和最顶部有横线
  • ¥15 R语言卸载之后无法重装,显示电脑存在下载某些较大二进制文件行为,怎么办
  • ¥15 java 的protected权限 ,问题在注释里
  • ¥15 这个是哪里有问题啊?
  • ¥15 关于#vue.js#的问题:修改用户信息功能图片无法回显,数据库中只存了一张图片(相关搜索:字符串)
  • ¥15 texstudio的问题,