HTML DOM 使用循环将分页的 XML 文件合并为单个文件
Posted
技术标签:
【中文标题】HTML DOM 使用循环将分页的 XML 文件合并为单个文件【英文标题】:HTML DOM Merge paged XML file into single file with a loop 【发布时间】:2021-02-03 06:24:19 【问题描述】:您好,我正在导入元素列表。该代码目前有效,但如果添加更多项目,它就不是面向未来的。 XML 使用唯一的键和分页(每 100 项一个新键)。
下面是我构建的函数的 php 代码。
<?php
$feedUrl = '[url of the feed]';
$doc1 = new DOMDocument();
$doc1->load($feedUrl);
$doc1_token = $doc1->getElementsByTagName('resumptionToken')[0]->nodeValue;
$doc2 = new DOMDocument();
$doc2->load($feedUrl . '&resumptionToken=' . $doc1_token);
$doc2_token = $doc2->getElementsByTagName('resumptionToken')[0]->nodeValue;
$doc3 = new DOMDocument();
$doc3->load($feedUrl . '&resumptionToken=' . $doc2_token);
$doc3_token = $doc3->getElementsByTagName('resumptionToken')[0]->nodeValue;
$doc4 = new DOMDocument();
$doc4->load($feedUrl . '&resumptionToken=' . $doc3_token);
$doc4_token = $doc4->getElementsByTagName('resumptionToken')[0]->nodeValue;
$doc5 = new DOMDocument();
$doc5->load($feedUrl . '&resumptionToken=' . $doc4_token);
$doc5_token = $doc5->getElementsByTagName('resumptionToken')[0]->nodeValue;
// get 'ListRecordes' element of document 1
$list_records = $doc1->getElementsByTagName('ListRecords')->item(0); //edited res - items
// iterate over 'item' elements of document 2
$items2 = $doc2->getElementsByTagName('record');
for ($i = 0; $i < $items2->length; $i ++)
$item2 = $items2->item($i);
// import/copy item from document 2 to document 1
$item1 = $doc1->importNode($item2, true);
// append imported item to document 1 'res' element
$list_records->appendChild($item1);
// iterate over 'item' elements of document 3
$items3 = $doc3->getElementsByTagName('record');
for ($i = 0; $i < $items3->length; $i ++)
$item3 = $items3->item($i);
// import/copy item from document 3 to document 1
$item1 = $doc1->importNode($item3, true);
// append imported item to document 1 'res' element
$list_records->appendChild($item1);
// iterate over 'item' elements of document 4
$items4 = $doc4->getElementsByTagName('record');
for ($i = 0; $i < $items4->length; $i ++)
$item4 = $items4->item($i);
// import/copy item from document 4 to document 1
$item1 = $doc1->importNode($item4, true);
// append imported item to document 1 'res' element
$list_records->appendChild($item1);
// iterate over 'item' elements of document 5
$items5 = $doc5->getElementsByTagName('record');
for ($i = 0; $i < $items5->length; $i ++)
$item5 = $$items5->item($i);
// import/copy item from document 5 to document 1
$item1 = $doc1->importNode($item5, true);
// append imported item to document 1 'res' element
$list_records->appendChild($item1);
$doc1->save('merged.xml'); //edited -added saving into xml file
我认为代码并不完美,因为如果我们添加的记录多于 600 条,则合并的 xml 中不会导入最新的记录。
除此之外还有一个问题。我们有嵌套的“”节点。我们只需要合并 "" 直接子节点。
<ListRecords>
<record>
<header>
...
</header>
<metadata>
<record xmlns="http://www.openarchives.org/OAI/2.0/" priref="100000002">
...
</record>
</metadata>
</record>
</ListRecords>
【问题讨论】:
【参考方案1】:您可以使用 Xpath 表达式来处理特定元素。在您的 sn-p 上,这将是 /ListRecords/record
。但是我认为它错过了用于元数据收集的开放档案倡议协议的名称空间声明的文档元素节点。它应该是这样的:
<OAI-PMH xmlns="http://www.openarchives.org/OAI/2.0/">
<ListRecords>
<record>
<header>
<identifier>oai:arXiv.org:hep-th/9901001</identifier>
</header>
</record>
</ListRecords>
</OAI-PMH>
要使用 Xpath 寻址命名空间,您需要为其注册一个前缀。然后将提要 url 放入一个数组并对其进行迭代:
$mergeDocument = new DOMDocument();
$mergeDocument->loadXML(
'<OAI-PMH xmlns="http://www.openarchives.org/OAI/2.0/"><ListRecords/></OAI-PMH>'
);
$mergeTarget = $mergeDocument->documentElement->firstChild;
foreach ($feedUrls as $feedUrl)
$document = new DOMDocument();
$document->load($feedUrl);
$xpath = new DOMXpath($document);
$xpath->registerNamespace('oai', 'http://www.openarchives.org/OAI/2.0/');
foreach ($xpath->evaluate('/oai:OAI-PMH/oai:ListRecords/oai:record') as $record)
$mergeTarget->appendChild($mergeDocument->importNode($record, TRUE));
$mergeDocument->formatOutput = TRUE;
echo $mergeDocument->saveXML();
【讨论】:
以上是关于HTML DOM 使用循环将分页的 XML 文件合并为单个文件的主要内容,如果未能解决你的问题,请参考以下文章
将分页添加到第 3 方模块 (OT-MiniNewsModule)