PHP 5.6.22 is available

XMLReader::next

(PHP 5 >= 5.1.0, PHP 7)

XMLReader::nextMove cursor to next node skipping all subtrees

Description

public bool XMLReader::next ([ string $localname ] )

Positions cursor on the next node skipping all subtrees.

Parameters

localname

The name of the next node to move to.

Return Values

Returns TRUE on success or FALSE on failure.

See Also

add a note add a note

User Contributed Notes 2 notes

up
0
ppp dot BOTSNEEDNOTAPPLY at salesfloor dot net
8 months ago
This method appears to follow these rules:

- if $localName names a sibling node, the cursor is moved to that node;
- if $localName names an ancestor node, the cursor is moved to the end of that node;
- if $localName names a node that is a sibling of any of the current node's ancestors, the cursor is moved to that node;
- otherwise the cursor is moved outside the document.

Note especially that this method never moves the cursor to child nodes.

For example, given this XML document

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

going from <root id="root"> to "bbb" places the cursor outside the document;
going from <aaa id="1"> to "bbb" places the cursor outside the document;
going from <aaa id="1"> to "aaa" places the cursor on <aaa id="3">;
going from <bbb id="1.1"> to "bbb" places the cursor on <bbb id="1.2">;
going from <bbb id="1.2"> to "bbb" places the cursor outside the document;
going from <bbb id="1.1"> to "ddd" places the cursor outside the document;
going from <bbb id="1.1"> to "aaa" places the cursor on </aaa>;
going from <bbb id="1.1"> to "ccc" places the cursor on <ccc id="2">;
going from <bbb id="1.1"> to "nonsuch" places the cursor outside the document;
going from <bbb id="1.1"> to "root" places the cursor on </root>;
going from <ddd id="3.1"> to "aaa" places the cursor on <aaa id="3.2">;
going from <ddd id="3.1"> to "eee" places the cursor outside the document;

Try it yourself:

<?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
"given this XML document\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
"going from <$xml->name id=\"$from\">";
        break;
      }
    }
  }

 
$xml->next($to);
 
$destination = "";
  if(
$xml->nodeType === \XmlReader::NONE) {
    if(!
$xml->read()) {
     
$destination = "outside the document";
    }
  }

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

  echo
" to \"$to\" places the cursor $destination;\n";

 
$xml->close();
}
?>
up
0
gholson19 at gmail dot com
1 year ago
To skip over deletion nodes in the xml extracted from a word document, do something like this:

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