0

我试图建立一个基于 xmldata 的数组结构。我相信这个问题与我如何处理有关$finalData。我最终想要一个包含三个记录数组的展平数组,但我想我需要先正确解析 XML 数据,然后再展平数据数组。我想修复解析 XML 数据的代码,所以我最初的问题是如何修复这段代码来解析 XML 数据,但随后我将研究如何展平最终的数据数组(我需要单独的record结构包含我最终需要的相关信息。我想你可以说我试图处理用户导入数据并最终只检索包含数据的各个组件。

public function processXml($xmldata,$finalData=array())
{
    $finalData = array();
    if($xmldata instanceof SimpleXMLElement){
        foreach($xmldata as $idata){
            $this->processXml($idata,$finalData);
        }
    } else {
        array_push($finalData,$xmldata);
    }
    return $finalData;  
}

这是 XML 数据(请注意,我不知道用户将在他的 XML 数据中导入什么,这只是我创建的测试数据):

`<?xml version="1.0" encoding="UTF-8"?>
     <configdata>
        <records>
             <somekey>
                <record>
                    <firstname>Jonathan</firstname>
                    <lastname>Kushner</lastname>
                </record>
                <record>
                    <firstname>Dustin</firstname>
                    <lastname>Kushner</lastname>
                </record>
                <record>
                    <firstname>Cameron</firstname>
                    <lastname>Kushner</lastname>
                </record>
            </somekey>
        </records>
    </configdata>`

注意:提供的答案使用 xpath 和 domdocument。我试图学习递归和展平,所以虽然它是一种更好的方法,但我仍然希望弄清楚如何仅使用递归和展平来实现这一点。

4

1 回答 1

0

与递归循环地毯式炸弹方法相比,使用XPath以精确的方式仅提取您想要的数据要好得多。

以下是您可以实现您想要的东西的方法:

// Create the document object
$xml = simplexml_load_string($xmlData);

$result = array();

// Get the <record> nodes and loop them
foreach ($xml->xpath('//record') as $record) {
    // to get the text data from a node in SimpleXML, just cast it to a string
    $result[] = array(
        'firstname' => (string) $record->firstname,
        'lastname' => (string) $record->lastname,
    );
}

print_r($result);

看到它工作

要在$record不知道其名称的情况下从 中获取所有子元素,您可以使用:

$result[] = array_map(
    'strval', 
     iterator_to_array($record->children())
);

请注意,同名元素(在 XML 中可能)在数组中不起作用。这里只有最后一个具有相同名称的元素会存在。

编辑

这仍然可以使用 XPath 完成,但是您需要使用 DOM 而不是 SimpleXML(这应该不是问题,它随处可用)。你可以这样做:

// Create the document object
$doc = new DOMDocument;

// This is required in order to ignore the pretty-print whitspace
$doc->preserveWhiteSpace = false;

// load the data into the object
$doc->loadXML($xmlData);
$xpath = new DOMXpath($doc);

$result = array();

// Get the text nodes and loop them
foreach ($xpath->query('//text()') as $record) {
    $result[] = $record->data;
}

print_r($result);

看到它工作

于 2013-03-15T16:42:21.880 回答