在PHP中将XML转换为ARRAY后,未保留ARRAY的顺序

时间:2012-09-29 18:41:57

标签: php xml xml-parsing

在PHP中使用simplexml_file_load后,我尝试使用我在Php.NET(http://www.php.net/manual/en/ref.simplexml.php)中找到的一些代码(XmlToArray())将xml转换为数组,以便我可以处理响应然后执行将其发布到给定的URL。

但是,XML文档中定义的顺序不是我在执行print_r(数组)时在终端中显示数组的方式。

有没有办法维护数组中XML中列出的相同顺序?任何帮助/方向将不胜感激。

这是我的机器本地的xml:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<order xmlns="http://www.shutterfly.com/orderv2/order">
    <version>2.0</version>
    <orderNo>sfly.000020513524-7001536_28935-tb.33</orderNo>
    <orderDate>2012-09-21 09:52:53 PDT</orderDate>
    <processing>
        <statusCallback>http://orderfulfillment.shutterfly.com/ogateway-test/status/sfly/xpressdocs/
        </statusCallback>
    </processing>
    <suborders>
        <suborder>
            <suborderNo>51917</suborderNo>
            <deliveryEstimate>
                <earliest>2012-10-01 00:00:00 PDT</earliest>
                <latest>2012-10-05 00:00:00 PDT</latest>
            </deliveryEstimate>
            <greeting>
                <line1>Ordered for you by Andrew Mullen on 09/21/12.</line1>
                <line2>Save 20% on Holiday Cards November 20 - 30 at Shutterfly
                </line2>
            </greeting>
            <shipAddr>
                <name>burkina faso</name>
                <address1>1234 burkina road</address1>
                <address2></address2>
                <city>yako</city>
                <region>R21</region>
                <postCode></postCode>
                <countryCode>BF</countryCode>
                <countryName>Burkina Faso</countryName>
            </shipAddr>
            <shipMethod>INTLSTD</shipMethod>
            <additionalFulfillers>false</additionalFulfillers>
            <items>
                <item>
                    <itemNo>36</itemNo>
                    <sku>6X8FLATCARD06</sku>
                    <description>6x8 Stationery Card - Stacy Claire Boyd</description>
                    <quantity>1</quantity>
                    <product>
                        <stationery>
                            <formFactor>6x8</formFactor>
                            <paperFinish>MATTE</paperFinish>
                            <orientation>LANDSCAPE</orientation>
                            <image>
                                <location>http://orderfulfillment.shutterfly.com/fulfillment-test/image/1200/000020513524-7001536_28935--164044--315625--canvas.jpg
                                </location>
                            </image>
                            <boc>
                                <location>http://orderfulfillment.shutterfly.com/fulfillment-test/image/1200/000020513524-7001536_28935--164044--315626--canvas.jpg
                                </location>
                            </boc>
                            <copyright>
                                <text>6X8FLATCARD06</text>
                            </copyright>
                        </stationery>
                    </product>
                    <envelopes>
                        <envelope>
                            <toAddress>
                                <font>
                                    <fontName>Arial</fontName>
                                    <fontSize>12</fontSize>
                                </font>
                                <name>FPO Tester</name>
                                <companyTitle></companyTitle>
                                <address1>PSC 812 Box 2640</address1>
                                <address2></address2>
                                <city>FPO</city>
                                <region>AE</region>
                                <postCode>09627</postCode>
                                <countryCode>USA</countryCode>
                                <countryName>United States of America</countryName>
                            </toAddress>
                            <fromAddress>
                                <font>
                                    <fontName>Arial</fontName>
                                    <fontSize>12</fontSize>
                                </font>
                                <name>Andrew Mullen</name>
                                <companyTitle></companyTitle>
                                <address1>2333 W. El Moro Circle</address1>
                                <address2></address2>
                                <city>Mesa</city>
                                <region>AZ</region>
                                <postCode>85202</postCode>
                                <countryCode>USA</countryCode>
                                <countryName>United States of America</countryName>
                            </fromAddress>
                        </envelope>
                    </envelopes>
                </item>
            </items>
        </suborder>
    </suborders>
</order>

这是我从PHP.net中选择的XMLToArray():

function XMLToArray($xml)
{
    if ($xml instanceof SimpleXMLElement) {
        $children = $xml->children();
        $return = null;
    }

    foreach ($children as $element => $value) {
        if ($value instanceof SimpleXMLElement) {
            $values = (array) $value->children();

            if (count($values) > 0) {
                $return[$element] = XMLToArray($value);
            } else {
                if (!isset($return[$element])) {
                    $return[$element] = (string) $value;
                } else {
                    if (!is_array($return[$element])) {
                        $return[$element] = array($return[$element], (string) $value);
                    } else {
                        $return[$element][] = (string) $value;
                    }
                }
            }
        }
    }

    if (is_array($return)) {
        return $return;
    } else {
        return $false;
    }
}

提前致谢。问候。

1 个答案:

答案 0 :(得分:0)

当我测试提供的代码时,我发现它与你提供的xml片段工作正常,但是如果添加其他项目,例如它在数组输出中丢失了它们。

我可以建议您尝试使用这个功能,而不是调试功能,这似乎对我有用:

来自Frederic 2008 @ Source of code sample

/**
 * Parse a SimpleXMLElement object recursively into an Array.
 * Attention: attributes skipped
 *
 *
 * @param $xml The SimpleXMLElement object
 * @param $arr Target array where the values will be stored
 * @return NULL
 */
private function convertXmlObjToArr( $obj, &$arr )
{
    $children = $obj->children();
    $executed = false;
    foreach ($children as $elementName => $node)
    {
        if( array_key_exists( $elementName , $arr ) )
        {
            if(array_key_exists( 0 ,$arr[$elementName] ) )
            {
                $i = count($arr[$elementName]);
                $this->convertXmlObjToArr ($node, $arr[$elementName][$i]);    
            }
            else
            {
                $tmp = $arr[$elementName];
                $arr[$elementName] = array();
                $arr[$elementName][0] = $tmp;
                $i = count($arr[$elementName]);
                $this->convertXmlObjToArr($node, $arr[$elementName][$i]);
            }
        }
        else
        {
            $arr[$elementName] = array();
            $this->convertXmlObjToArr($node, $arr[$elementName]);   
        }
        $executed = true;
    }
    if(!$executed&&$children->getName()=="")
    {
        $arr = (String)$obj;
    }

    return ;
}