简体   繁体   English

PHP递归收集SimpleXMLElement数据并展平数组

[英]PHP Recursively collect SimpleXMLElement data and flatten array of arrays

Im trying to build an array structure based off of xmldata. 我试图建立基于xmldata的数组结构。 I believe the issue has to do with how Im handling $finalData . 我认为问题与Im如何处理$finalData I eventually want a flattened array containing three arrays of records, but I imagine I need to first parse the XML data correctly and then work on flattening the array of data. 我最终想要一个包含三个记录数组的扁平化数组,但是我想我需要首先正确解析XML数据,然后再对数据数组进行扁平化。 I wanted to fix the code to parse the XML data, so my initial question is how do I fix this code to parse the XML data, but then I was going to work on how to flatten the final data array(i need the individual record structures that contain the pertinent information i eventually need. I guess you can say Im trying to handle a user import of data and ultimately retrieve just the individual components that contain the data. 我想修复代码以解析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;  
}

Here's the XML Data (note that I do not know what the user will be importing in his XML data, this is just test data that i created): 这是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>`

NOTE: The answers provided use xpath and domdocument. 注意:提供的答案使用xpath和domdocument。 Im trying to learn recursion and flattening so although it is a better approach, I still wish to figure out how to implement this using just recursion and flattening. 我试图学习递归和展平,因此尽管这是一种更好的方法,但我仍然希望弄清楚如何仅使用递归和展平来实现这一点。

Rather than the recursive loop carpet-bomb approach, it is far better to use XPath to extract only the data you want in a precise way. 与其使用递归循环地毯式炸弹方法,不如使用XPath以精确的方式仅提取所需的数据要好得多。

Here's how you can acheive what you want: 您可以通过以下方式实现自己想要的:

// 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);

See it working 看到它正常工作

To take all child elements from the $record without knowing it's name, you can use: 要从$record获取所有子元素而不知道其名称,可以使用:

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

Take note that same-names elements (which is possible in XML) will not work in an array. 请注意,同名元素(在XML中是可能的)在数组中不起作用。 Here only the last element with the same name will survive. 在这里,只有具有相同名称的最后一个元素将生存。

Edit 编辑

This can also still be done with XPath but you will need to use DOM instead of SimpleXML (this shouldn't be a problem, it's available everywhere). 这仍然可以使用XPath完成,但是您将需要使用DOM而不是SimpleXML(这应该没问题,它随处可见)。 You can do something like this: 您可以执行以下操作:

// 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);

See it working 看到它正常工作

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM