PHP Conference Japan 2024

XMLReader::next

(PHP 5 >= 5.1.0, PHP 7, PHP 8)

XMLReader::next跳过所有子树,将光标移动到下一个节点

描述

public XMLReader::next(?string $name = null): bool

将光标定位在下一个节点上,跳过所有子树。如果不存在这样的节点,则光标将移动到文档末尾。

参数

name

要移动到的下一个节点的名称。

返回值

成功返回 true,失败返回 false

变更日志

版本 描述
8.0.0 name 现在可以为 null。

参见

添加注释

用户贡献的笔记 3 条笔记

ppp dot BOTSNEEDNOTAPPLY at salesfloor dot net
9 年前
此方法似乎遵循以下规则:

- 如果 $localName 指定一个同级节点,则光标将移动到该节点;
- 如果 $localName 指定一个祖先节点,则光标将移动到该节点的末尾;
- 如果 $localName 指定一个节点,该节点是当前节点的任何祖先的同级节点,则光标将移动到该节点;
- 否则,光标将移动到文档之外。

尤其要注意的是,此方法永远不会将光标移动到子节点。

例如,给定此XML文档

<?xml version="1.0" encoding="UTF-8"?>
<root id="root" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<aaa id="1">
<bbb id="1.1"></bbb>
<bbb id="1.2"></bbb>
</aaa>
<ccc id="2" />
<aaa id="3">
<ddd id="3.1">
<aaa id="3.1.1"></aaa>
</ddd>
<aaa id="3.2"></aaa>
</aaa>
<aaa id="4">
<eee id="4.1"></eee>
</aaa>
</root>

从 <root id="root"> 到 "bbb" 将光标置于文档之外;
从 <aaa id="1"> 到 "bbb" 将光标置于文档之外;
从 <aaa id="1"> 到 "aaa" 将光标置于 <aaa id="3"> 上;
从 <bbb id="1.1"> 到 "bbb" 将光标置于 <bbb id="1.2"> 上;
从 <bbb id="1.2"> 到 "bbb" 将光标置于文档之外;
从 <bbb id="1.1"> 到 "ddd" 将光标置于文档之外;
从 <bbb id="1.1"> 到 "aaa" 将光标置于 </aaa> 上;
从 <bbb id="1.1"> 到 "ccc" 将光标置于 <ccc id="2"> 上;
从 <bbb id="1.1"> 到 "nonsuch" 将光标置于文档之外;
从 <bbb id="1.1"> 到 "root" 将光标置于 </root> 上;
从 <ddd id="3.1"> 到 "aaa" 将光标置于 <aaa id="3.2"> 上;
从 <ddd id="3.1"> 到 "eee" 将光标置于文档之外;

自己试试

<?php

$document
= <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<root id="root" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<aaa id="1">
<bbb id="1.1"></bbb>
<bbb id="1.2"></bbb>
</aaa>
<ccc id="2" />
<aaa id="3">
<ddd id="3.1">
<aaa id="3.1.1"></aaa>
</ddd>
<aaa id="3.2"></aaa>
</aaa>
<aaa id="4">
<eee id="4.1"></eee>
</aaa>
</root>
XML;

$filename = "/tmp/xmlreader.php.xml";
file_put_contents($filename, $document);

echo
"给定此XML文档\n\n$document\n\n";

showNext("root", "bbb");
showNext("1", "bbb");
showNext("1", "aaa");
showNext("1.1", "bbb");
showNext("1.2", "bbb");
showNext("1.1", "ddd");
showNext("1.1", "aaa");
showNext("1.1", "ccc");
showNext("1.1", "nonsuch");
showNext("1.1", "root");
showNext("3.1", "aaa");
showNext("3.1", "eee");

function
showNext($from, $to) {
global
$filename;

$xml = new \XmlReader();
$xml->open("file://$filename");
while (
$xml->read()) {
if (
$xml->nodeType === \XmlReader::ELEMENT) {
if (
$xml->getAttribute("id") == $from) {
echo
"从 <$xml->name id=\"$from\"> 开始;";
break;
}
}
}

$xml->next($to);
$destination = "";
if(
$xml->nodeType === \XmlReader::NONE) {
if(!
$xml->read()) {
$destination = "文档外部";
}
}

if(!
$destination) {
if (
$xml->nodeType === \XmlReader::END_ELEMENT) {
$destination = "在 </$xml->name> 上;";
} else if (
$xml->nodeType === \XmlReader::ELEMENT) {
$destination = "在 <$xml->name id=\"" . $xml->getAttribute("id") . "\"> 上;";
}
}

echo
"到 \"$to\" 将光标置于 $destination;\n";

$xml->close();
}
?>
Quiet Noise
5年前
不带参数的 next() 函数会将光标移动到与当前光标相同深度的下一个同级节点。
示例
1. 如果当前光标位于一个开始 ELEMENT 节点上,next() 函数会将光标移动到该元素闭合标签的下一行节点(如果每个标签都在单独一行),或者移动到同一深度下一个节点的开始标签。
2. 如果当前光标位于一个 TEXT 节点上,next() 函数会将光标移动到其相邻的开始标签(如果存在)。

如果在给定深度下没有更多节点,next() 函数会将光标移动到父级元素的闭合标签 (END_ELEMENT)。
gholson19 at gmail dot com
9 年前
为了跳过从 Word 文档中提取的 XML 中的删除节点,可以尝试如下操作:

if ($paragraph->nodeType == XMLREADER::ELEMENT && $paragraph->name === 'w:del'){$paragraph->next();}
To Top