【问题标题】:PHP XMLReader read , edit Node , write XMLWriterPHP XMLReader 读取、编辑节点、编写 XMLWriter
【发布时间】:2014-01-30 15:44:33
【问题描述】:

我有一个非常非常大的 XML 文件(数百万条记录)。由于速度和内存限制,我计划使用XMLReader/XMLWriter

我需要读取文件,获取一条记录,更改其属性,最后再次保存 XML。

为了进行测试,我创建了一个 XML 文件并使用这些行将一些记录写入其中:

$doc = new XMLWriter();  
$doc->openURI($xmlFile);  
$doc->startDocument('1.0','UTF-8');  
$doc->setIndent(4);   
$doc->startElement('DBOS'); 
for($r=0;$r<10; $r++){
    $doc->startElement('ITEMS');
    for($i=0;$i<5; $i++){
        $doc->startElement('ITEM');  
        $doc->writeAttribute('id', $r.'-'.$i);
        $doc->endElement();
    }
    $doc->endElement();
}
$doc->endElement();  
$doc->endDocument();   
$doc->flush();

我用这个又读了一遍:

$reader = new XMLReader();
if (!$reader->open($xmlFile)){
    die("Failed to open 'data.xml'");
}
while($reader->read()){
    if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'ITEMS') {
        $node = $reader->expand();
        $items = $node->childNodes;
        foreach ($items as $ik => $itm ){
            print $itm->textContent.'<br/>';
            // how to change the ID Attribute of a Node (DomNode) and save changes to the original XML File 
        }
        break;
    }
}
$reader->close();

我的问题:如何更改DomNodeid 属性并再次使用XMLWriter 将更改保存到原始XML 文件?

【问题讨论】:

    标签: php xml xmlreader xmlwriter data-manipulation


    【解决方案1】:

    如何更改DomNode的id属性,并再次使用XMLWriter将更改保存到原始XML文件?

    这样不行。如果你同时使用XMLReaderXMLWriter同一个文件进行操作,该文件将被作者截断,阅读器将吐出错误并停止工作。

    但是,您可以对不同的文件进行操作。

    因此,您可以做的是使用 XMLReader 来读取文档,并在对其进行操作时使用 XMLWriter 根据您的内容写入另一个文档阅读并偶尔修改。完成后,您可以将新写入的文件重命名为旧文件名。

    示例

    对于一个 XML 文档(例如,XMLReaderXMLWriter 对非常大的文档来说自然有意义),像这个在你的问题之后建模一点:

    <DBOS>
        <ITEMS>
            <ITEM>item #1</ITEM>
            <ITEM>item #2</ITEM>
            <ITEM>item #3</ITEM>
        </ITEMS>
        <ITEMS>
            <ITEM>item #4</ITEM>
            <ITEM>item #5</ITEM>
        </ITEMS>
    </DBOS>
    

    一个有效的代码示例是:

    <?php
    /*
     * This file is part of the XMLReaderIterator package.
     *
     * Copyright (C) 2012, 2014 hakre <http://hakre.wordpress.com>
     *
     * Example: Write XML with XMLWriter while reading from XMLReader with XMLWriterIteration
     */
    
    require('xmlreader-iterators.php'); // require XMLReaderIterator library
    
    $xmlInputFile  = 'data/dobs-items.xml';
    $xmlOutputFile = 'php://output';
    
    $reader = new XMLReader();
    $reader->open($xmlInputFile);
    
    $writer = new XMLWriter();
    $writer->openUri($xmlOutputFile);
    
    $iterator = new XMLWritingIteration($writer, $reader);
    
    $writer->startDocument();
    
    $itemsCount = 0;
    $itemCount  = 0;
    foreach ($iterator as $node) {
        $isElement = $node->nodeType === XMLReader::ELEMENT;
    
    
        if ($isElement && $node->name === 'ITEMS') {
            // increase counter for <ITEMS> elements and reset <ITEM> counter
            $itemsCount++;
            $itemCount = 0;
        }
    
        if ($isElement && $node->name === 'ITEM') {
            // increase <ITEM> counter and insert "id" attribute
            $itemCount++;
            $writer->startElement($node->name);
            $writer->writeAttribute('id', $itemsCount . "-" . $itemCount);
            if ($node->isEmptyElement) {
                $writer->endElement();
            }
        } else {
            // handle everything else
            $iterator->write();
        }
    }
    
    $writer->endDocument();
    

    然后输出是(以标准输出为例,可以使用任何有效的 PHP 文件名):

    <?xml version="1.0"?>
    <DBOS>
        <ITEMS>
            <ITEM id="1-1">item #1</ITEM>
            <ITEM id="1-2">item #2</ITEM>
            <ITEM id="1-3">item #3</ITEM>
        </ITEMS>
        <ITEMS>
            <ITEM id="2-1">item #4</ITEM>
            <ITEM id="2-2">item #5</ITEM>
        </ITEMS>
    </DBOS>
    

    如本例所示,id 属性是根据不同计数器变量的编号添加的。

    感谢$iterator-&gt;write()XMLWritingIteration 可以轻松处理所有其他节点和案例。

    示例和代码是the XMLReaderIterator package 的一部分。还有另一个例子是基于 XMLReader 创建一个 DOMDocument,它是an answer to "How to distinguish between empty element and null-size string in DOMDocument?" 的一部分。

    【讨论】:

      猜你喜欢
      • 2011-07-11
      • 1970-01-01
      • 2011-05-23
      • 1970-01-01
      • 2011-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多