区分PHP XPath中的相同节点名称

时间:2017-03-10 06:33:39

标签: php xpath domxpath

我正在使用 PHP DOM XPath 来阅读 XML 。 XML有以下结构,我遇到了问题

<details>
    <name>name1</name>
    <address>address1</address>
</details>
<details>
    <name>name2</name>
    <mobile>mobileNum</mobile>
    <address>address2</address>
</details>

我有像

这样的数组
  array(
        'name',
        'mobile',
        'address'
    ); 

我使用此数组并从XML中读取值并将该值存储在其他数组中,但在第一条记录中移动号码不存在,因此它从第二条记录中读取移动号码并将其插入第一条记录中

预期输出

array
(

    [0] => array(

                'person_name' = name1,
                'address' = address1
                )
    [1] => array(

                'person_name' = name1,
                'mobile_no' = mobileNum
                'address' = address1
                )
)

但我输出为

array
(

    [0] => array(

                'person_name' = name1,
                'mobile_no' = mobileNum
                'address' = address1
                )
    [1] => array(

                'person_name' = name1,
                'address' = address1
                )
)

如何区分具有相同名称的两个节点之间的值。

读取XML的代码是

$nodes = array
(
    'person_name' => 'name',
    'mobile_no'   => 'mobile',
    'address'     => 'address'
)

$final_data = array();

$node_values = '';

foreach($nodes as $key => $data)
{   
    $node_values = $xml->xpath('//details'.$data); 

    $node_values = json_decode(json_encode((array)$node_values), TRUE);

    if(!empty($node_values))    
    {   
        $i = 0;

        foreach($node_values as $d)
        {
            $final_data[$i][$key] = trim($d[0]);

            $i++;
        }
    }
}

1 个答案:

答案 0 :(得分:1)

这是一个工作示例,其中包含解释其工作原理的评论:

https://3v4l.org/ICO5i

<?php

// First of all, I've added <root> element to your XML document,
// because otherwise it's invalid. 
// But it's not important for the rest of the code.
//
// Also I've added additional <somethingelse> tag to show that filtering is working
$xmlString = '<root><details>
    <name>name1</name>
    <address>address1</address>
</details>
<details>
    <name>name2</name>
    <mobile>mobileNum</mobile>
    <address>address2</address>
    <somethingelse>This will be filtered</somethingelse>
</details></root>';


$xml = new SimpleXMLElement($xmlString);
//array_flip to get node names as keys for later foreach loop
$nodes = array_flip(array
(
    'person_name' => 'name',
    'mobile_no'   => 'mobile',
    'address'     => 'address',
));

$final_data = array();

//Here are all <details> sections' data in array.
$node_values = $xml->xpath('//details'); 
$node_values = json_decode(json_encode((array)$node_values), TRUE);

//this loop filters XML data from keys not existing in $nodes,
// which are the only that you want to keep
foreach($node_values as $node) {
    $final_data[] = array_intersect_key($node, $nodes);
}

var_dump($final_data);

我假设您要过滤未在$nodes数组中列出的XML数据。否则,如果您不介意拥有超出需求的数据,则可以跳过foreach循环并使用$node_values作为最终数据。