【问题标题】:Stream parse 4GB XML file and write part of file to new XML file in PHP流解析 4GB XML 文件并将部分文件写入 PHP 中的新 XML 文件
【发布时间】:2013-09-20 00:25:59
【问题描述】:

我正在尝试对大约 4GB 的 XML 文件进行流式解析,并将其中的一部分写入 PHP 中的新 XML 文件。

~4GB XML 文档的结构是这样的,我试图保留<doc> 元素及其<title></title> <url></url><abstract></abstract> 子元素。

但是当我运行这个脚本时,我得到的只是一个每行有一个<doc /> 的文件。所以基本上它是复制<doc> 元素并使它们自动关闭,但是不复制其子代。

<?php

    $interestingNodes = array('title','url','abstract');
    $xmlObject = new XMLReader();
    $xmlObject->open('file.xml');

    $xmlOutput = new XMLWriter();
    $xmlOutput->openURI('destfile.xml');
    $xmlOutput->setIndent(true);
    $xmlOutput->setIndentString("   ");
    $xmlOutput->startDocument('1.0', 'UTF-8');

    while($xmlObject->read()){
        if($xmlObject->name == 'doc'){
             $xmlOutput->startElement('doc');
             $xmlObject->readInnerXML();
             if(array_search($xmlObject->name, $interestingNodes)){
                 $xmlOutput->startElement($xmlObject->name);
                 $xmlOutput->text($xmlObject->value);
                 $xmlOutput->endElement(); //close the current node
             }
             $xmlOutput->endElement(); //close the doc node
        }
    }

    $xmlObject->close();
    $xmlOutput->endDocument();
    $xmlOutput->flush();

?>

file.xml 如下所示:

<feed>
    <doc>
        <title>Title of first doc is here</title>
        <url>URL is here</url>
        <abstract>Abstract is here...</abstract>
        <links>
            <sublink>Link is here</sublink>
            <sublink>Link is here</sublink>
            <sublink>Link is here</sublink>
            <sublink>Link is here</sublink>
            <sublink>Link is here</sublink>
       </link>
    </doc>
    <doc>
        <title>Title of second doc is here</title>
        <url>URL is here</url>
        <abstract>Abstract is here...</abstract>
        <links>
            <sublink>Link is here</sublink>
            <sublink>Link is here</sublink>
            <sublink>Link is here</sublink>
            <sublink>Link is here</sublink>
            <sublink>Link is here</sublink>
        </link>
    </doc>
 </feed>

这就是我希望 destfile.xml 的样子:

    <doc>
        <title>Title of first doc is here</title>
        <url>URL is here</url>
        <abstract>Abstract is here...</abstract>
    </doc>
    <doc>
        <title>Title of second doc is here</title>
        <url>URL is here</url>
        <abstract>Abstract is here...</abstract>
    </doc>

但是当我运行上面的那个脚本时,我得到的只是:

<doc />
<doc />
<doc />
<doc />
<doc />
<doc />
/* And many, many more <doc />s */

【问题讨论】:

    标签: php xml xml-parsing large-data


    【解决方案1】:

    我相信以下内容会满足您的要求:

    <?php
    
        $interestingNodes = array('title','url','abstract');
        $xmlObject = new XMLReader();
        $xmlObject->open('file.xml');
    
        $xmlOutput = new XMLWriter();
        $xmlOutput->openURI('destfile.xml');
        $xmlOutput->setIndent(true);
        $xmlOutput->setIndentString("   ");
        $xmlOutput->startDocument('1.0', 'UTF-8');
    
        while($xmlObject->read()){
            if($xmlObject->name == 'doc'){
                if($xmlObject->nodeType==XMLReader::END_ELEMENT) $xmlOutput->endElement();
                else $xmlOutput->startElement('doc');
            }
            if(in_array($xmlObject->name, $interestingNodes)){
                $xmlOutput->startElement($xmlObject->name);
                $xmlOutput->text($xmlObject->readString());
                $xmlOutput->endElement(); //close the current node
            }
        }
    
        $xmlObject->close();
        $xmlOutput->endDocument();
        $xmlOutput->flush();
    
    ?>
    

    【讨论】:

    • array_search 需要 !==false 检查,否则您将永远无法获得“标题”(位置 0)
    猜你喜欢
    • 2021-12-07
    • 2015-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-14
    • 1970-01-01
    • 1970-01-01
    • 2011-07-21
    相关资源
    最近更新 更多