PHP XMLReader处理缺少的元素

时间:2011-10-21 19:26:46

标签: php xmlreader

我正在使用XMLReader来解析我无法控制的文件。该文件缺少一些元素,如下所示。书2中缺少一个info元素,我仍然希望将它添加到数组中。我意识到我可以使用XMLReader和SimpleXML的组合...但是我想看看这是否可行?

<book>
    <title>book 1</title>
    <info>book 1 info</info>
</book>
<book>
    <title>book 2</title>
</book>
<book>
    <title>book 3</title>
    <info>book 3 info</info>
</book>

我有以下XMLReader函数:

<?php
function parseXML($args){
    extract($args);
    $xml = new XMLReader();
    $xml->open($file) or die('Cannot open file');

    while($xml->read()){
        switch($xml->nodeType){
            case(XMLREADER::ELEMENT):{
                if(in_array($xml->localName, $nodes, true)){
                    $lName = $xml->localName;
                    $val = $xml->readString();
                    $xml->read();

                    $child[$lName] = trim($val);
                    if($lName == end($nodes)){
                        $arr[] = $child;
                    }
                }
            }
            break;
        }
    }
    $xml->close($file);
    return $arr;
}
$settings = array(
    'file' => 'books.xml',
    'nodes' => array('name', 'info')
);
$books = parseXML($settings);
var_dump($books);
?>

产生:

Array
(
[0] => Array
    (
        [name] => book 1
        [info] => book 1 info
    )

[1] => Array
    (
        [name] => book 3
        [info] => book 3 info
    )
)

1 个答案:

答案 0 :(得分:2)

你可以稍微重新思考一下你的逻辑。下面的代码段为每个$book元素构建一个<book>数组,每次使用默认值(空字符串)时,如果<name><info>不存在这本书。

当达到<name><info>元素时,其内容会添加到当前$book数组中。

到达</book>时,$book数组会添加到$books的主数组中。

构建$books

function parseXML($args){
    extract($args);

    $xml   = new XMLReader();
    $xml->open($file) or die('Cannot open file');

    $books = array();

    while ($xml->read()) {
        // <book> - start a new child array with default values
        if ($xml->nodeType === XMLReader::ELEMENT 
         && $xml->localName === 'book') {
            $book = array_fill_keys($nodes, '');
        // </book> - add the child array to main array
        } elseif ($xml->nodeType === XMLReader::END_ELEMENT 
               && $xml->localName === 'book') {
            $books[] = $book;
        // <info> or <title> - add to child array
        } elseif ($xml->nodeType === XMLReader::ELEMENT 
               && in_array($xml->localName, $nodes, TRUE)) {
            $name = $xml->localName;
            $val  = $xml->readString();
            $book[$name] = trim($val);
        }
    }

    $xml->close();
    return $books;
}

产生的数组

$books = array(
  array('title' => 'book 1', 'info' => 'book 1 info'),
  array('title' => 'book 2', 'info' => ''),
  array('title' => 'book 3', 'info' => 'book 3 info'),
);