我有一个非常非常大的 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();
我的问题:如何更改 DomNode 的 id 属性并将更改保存到原始 XML 文件使用 XMLWriter 又是?
最佳答案
How to change the id attribute of a DomNode and save changes to the original XML File using XMLWriter again?
这样不行。如果你同时使用 XMLReader 和 XMLWriter 对同一个文件进行操作,文件将被写入者截断,读取者将吐出错误并停止工作。
但是,您可以对不同 文件进行操作。
因此,您可以做的是使用 XMLReader 读取文档,并在对其进行操作时使用 XMLWriter 根据您的内容写入另一个文档阅读并偶尔修改。完成后,您可以将新写入的文件重命名为旧文件名。
对于 XML 文档(例如,XMLReader 和 XMLWriter 对非常大的文档来说很自然地有意义)像这样模仿您的问题:
<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->write(),XMLWritingIteration 让这一切变得简单,因为它处理所有其他节点和案例。
示例和代码是 the XMLReaderIterator package 的一部分。还有另一个例子是基于 XMLReader 创建一个 DOMDocument,它是 an answer to "How to distinguish between empty element and null-size string in DOMDocument?" 的一部分。
关于PHP XMLReader 读取、编辑 Node 、写入 XMLWriter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21065150/
我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的
文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,
我想知道Ruby用来在命令行打印这些东西的输出流:irb(main):001:0>a="test"=>"test"irb(main):002:0>putsatest=>nilirb(main):003:0>a=>"test"$stdout是否用于irb(main):002:0>和irb(main):003:0>?而且,在这两次调用之间,$stdout的值是否有任何变化?另外,有人能告诉我打印/写入这些内容的Ruby源代码吗? 最佳答案 是的。而且很容易向自己测试/证明。在命令行试试这个:ruby-e'puts"foo"'>test.
s=Socket.new(Socket::AF_INET,Socket::SOCK_STREAM,0)s.connect(Socket.pack_sockaddr_in('port','hostname'))ssl=OpenSSL::SSL::SSLSocket.new(s,sslcert)ssl.connect从这里开始,如果ssl连接和底层套接字仍然是ESTABLISHED,或者它是否在默认值7200之后进入CLOSE_WAIT,我想检查一个线程几秒钟甚至更糟的是在实际上不需要.write()或.read()的情况下关闭。是用select()、IO.select()还是其他方法完成
在Ruby1.9中,我如何从ARGF中读取CSV?我尝试了以下方法,但没有打印任何内容:require'csv'CSV(ARGF).readdo|row|prowendhttp://www.ruby-doc.org/core-1.9.3/ARGF.htmlhttp://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV.html 最佳答案 如果你想偷懒你可以试试:CSV.new(ARGF.file).eachdo|row|...end来源:http://www.ruby-doc.org/std
我正在编写一个ruby程序,它应该执行另一个程序,通过stdin向它传递值,从它的stdout读取响应,然后打印响应。这是我目前所拥有的。#!/usr/bin/envrubyrequire'open3'stdin,stdout,stderr=Open3.popen3('./MyProgram')stdin.puts"helloworld!"output=stdout.readerrors=stderr.readstdin.closestdout.closestderr.closeputs"Output:"puts"-------"putsoutputputs"\nErrors:"p