Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP XMLReader读取、编辑节点、写入XMLWriter_Php_Xml_Xmlreader_Xmlwriter_Data Manipulation - Fatal编程技术网

PHP XMLReader读取、编辑节点、写入XMLWriter

PHP XMLReader读取、编辑节点、写入XMLWriter,php,xml,xmlreader,xmlwriter,data-manipulation,Php,Xml,Xmlreader,Xmlwriter,Data Manipulation,我有一个非常大的XML文件(数百万条记录)。由于速度和内存限制,我计划使用XMLReader/XMLWriter 我需要读取文件,获取一条记录,更改其属性,最后再次保存XML 为了进行测试,我创建了一个XML文件,并使用以下行将一些记录写入其中: $doc = new XMLWriter(); $doc->openURI($xmlFile); $doc->startDocument('1.0','UTF-8'); $doc->setIndent(4); $do

我有一个非常大的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();
$doc=newXMLWriter();
$doc->openURI($xmlFile);
$doc->startDocument('1.0','UTF-8');
$doc->setIndent(4);
$doc->startElement('DBOS');
对于($r=0;$rstartElement('ITEMS');
对于($i=0;$IStarElement($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();
$reader=newXMLReader();
如果(!$reader->open($xmlFile)){
die(“未能打开'data.xml'”);
}
而($reader->read()){
如果($reader->nodeType==XMLReader::ELEMENT&&$reader->name==ITEMS'){
$node=$reader->expand();
$items=$node->childNodes;
foreach($ik=>itm的项目){
打印$itm->text内容。“
”; //如何更改节点(DomNode)的ID属性并将更改保存到原始XML文件 } 打破 } } $reader->close();
我的问题:如何再次使用XMLWriter更改
DomNode
id
属性并将更改保存到原始XML文件

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

如果您同时使用和操作同一个文件,该文件将被写入程序截断,读卡器将抛出错误并停止工作

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

因此,您可以使用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>

项目#1
项目#2
项目#3
项目4
项目#5
工作代码示例如下:

<?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();
open($xmlInputFile);
$writer=newxmlwriter();
$writer->openUri($xmlOutputFile);
$iterator=newXMLWritingIteration($writer,$reader);
$writer->startDocument();
$itemscont=0;
$itemCount=0;
foreach($iterator作为$node){
$isElement=$node->nodeType===XMLReader::ELEMENT;
如果($isElement&&$node->name==='ITEMS'){
//增加元件的计数器并重置计数器
$itemscont++;
$itemCount=0;
}
如果($isElement&&$node->name==='ITEM'){
//增加计数器并插入“id”属性
$itemCount++;
$writer->startElement($node->name);
$writer->writeAttribute('id',$itemscont.-“$itemCount);
如果($node->isemptyelment){
$writer->endElement();
}
}否则{
//处理其他事情
$iterator->write();
}
}
$writer->endDocument();
然后输出为(标准输出的示例,可以使用任何有效的PHP文件名):


项目#1
项目#2
项目#3
项目4
项目#5
如本例所示,id属性是根据不同计数器变量的编号添加的

得益于
$iterator->write()
,XMLWritingIteration
可以轻松处理所有其他节点和案例

示例和代码是的一部分。还有另一个示例是基于XMLReader创建DOMDocument,它是的一部分

<?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>