Skip to content

Commit 409d64f

Browse files
committed
XMLReaderIterator v0.1.9.
- fix XML declaration detection (thanks David Paz) - added XMLReaderNode::expand() (thanks Thomas Weinert) - added XMLReaderTestCase - phpunit default configuration - build: added build.sh script
1 parent 21275f9 commit 409d64f

16 files changed

Lines changed: 605 additions & 109 deletions

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
### Changelog:
44

5+
- `0.1.9` maintenance release with fixes. added XMLReaderNode::expand().
6+
57
- `0.1.8` maintenance release with fixes.
68

79
- `0.1.7` maintenance release with fixes.

build.sh

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/usr/bin/env bash
2+
#
3+
# build script on clean checkout
4+
#
5+
6+
if [ ! -d vendor ]; then
7+
echo "installing build dependencies..."
8+
composer install
9+
fi
10+
11+
if [ ! -d vendor ]; then
12+
echo "build dependencies not installed!"
13+
exit 1
14+
fi
15+
16+
php -f build.php

build/include/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
### Changelog:
44

5+
- `0.1.9` maintenance release with fixes. added XMLReaderNode::expand().
6+
57
- `0.1.8` maintenance release with fixes.
68

79
- `0.1.7` maintenance release with fixes.

build/include/xmlreader-iterators.php

Lines changed: 73 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
*
2020
* @author hakre <http://hakre.wordpress.com>
2121
* @license AGPL-3.0 <http://spdx.org/licenses/AGPL-3.0>
22-
* @version 0.1.8
22+
* @version 0.1.9
2323
*/
2424

2525
/**
@@ -845,18 +845,42 @@ private function writeReaderImpl(XMLWriter $writer, XMLReader $reader) {
845845
*/
846846
class XMLReaderNode implements XMLReaderAggregate
847847
{
848-
public $name;
848+
/** @var XMLReader */
849849
private $reader;
850+
851+
/** @var int */
850852
private $nodeType;
851-
private $string;
852-
private $attributes;
853+
854+
/** @var string */
855+
private $name;
856+
857+
/** @var string */
858+
private $localName;
859+
860+
/**
861+
* cache for expansion into SimpleXMLElement
862+
*
863+
* @var null|SimpleXMLElement
864+
* @see asSimpleXML
865+
*/
853866
private $simpleXML;
854867

868+
/**
869+
* cache for XMLAttributeIterator
870+
*
871+
* @var null|XMLAttributeIterator
872+
* @see getAttributes
873+
*/
874+
private $attributes;
875+
876+
/** @var null|string */
877+
private $string;
878+
855879
public function __construct(XMLReader $reader)
856880
{
857-
$this->reader = $reader;
858-
$this->nodeType = $reader->nodeType;
859-
$this->name = $reader->name;
881+
$this->reader = $reader;
882+
$this->nodeType = $reader->nodeType;
883+
$this->name = $reader->name;
860884
}
861885

862886
public function __toString()
@@ -876,13 +900,12 @@ public function __toString()
876900
*/
877901
public function getSimpleXMLElement()
878902
{
879-
if (null === $this->simpleXML)
880-
{
903+
if (null === $this->simpleXML) {
881904
if ($this->reader->nodeType !== XMLReader::ELEMENT) {
882905
return null;
883906
}
884907

885-
$node = $this->getDocumentNode();
908+
$node = $this->expand();
886909
$this->simpleXML = simplexml_import_dom($node);
887910
}
888911

@@ -897,6 +920,7 @@ public function getSimpleXMLElement()
897920
public function asSimpleXML()
898921
{
899922
trigger_error('Deprecated ' . __METHOD__ . '() - use getSimpleXMLElement() in the future', E_USER_NOTICE);
923+
900924
return $this->getSimpleXMLElement();
901925
}
902926

@@ -944,11 +968,22 @@ public function getChildren()
944968
return new XMLChildIterator($this->reader);
945969
}
946970

971+
/**
972+
* @return string name
973+
*/
947974
public function getName()
948975
{
949976
return $this->name;
950977
}
951978

979+
/**
980+
* @return string local name
981+
*/
982+
public function getLocalName()
983+
{
984+
return $this->localName;
985+
}
986+
952987
public function getReader()
953988
{
954989
return $this->reader;
@@ -971,18 +1006,13 @@ public function readOuterXml()
9711006
return '';
9721007
}
9731008

974-
$node = $this->getDocumentNode();
1009+
$doc = new DOMDocument();
1010+
1011+
$doc->preserveWhiteSpace = false;
1012+
$doc->formatOutput = true;
1013+
1014+
$node = $this->expand($doc);
9751015

976-
/**
977-
* FIXME this var hint is un-necessary
978-
*
979-
* @link http://youtrack.jetbrains.com/issue/WI-23810
980-
*
981-
* @var $doc DOMDocument
982-
*/
983-
$doc = $node->ownerDocument;
984-
$doc->formatOutput = true;
985-
$node = $doc->appendChild($node);
9861016
return $doc->saveXML($node);
9871017
}
9881018

@@ -993,16 +1023,28 @@ public function readOuterXml()
9931023
* or getting a SimpleXMLElement out of it @see getSimpleXMLElement
9941024
*
9951025
* @throws BadMethodCallException
996-
*
1026+
* @param DOMNode $basenode
9971027
* @return DOMNode
9981028
*/
999-
private function getDocumentNode() {
1000-
if (false === $node = $this->reader->expand()) {
1029+
public function expand(DOMNode $basenode = null)
1030+
{
1031+
if (null === $basenode) {
1032+
$basenode = new DomDocument();
1033+
}
1034+
1035+
if ($basenode instanceof DOMDocument) {
1036+
$doc = $basenode;
1037+
} else {
1038+
$doc = $basenode->ownerDocument;
1039+
}
1040+
1041+
if (false === $node = $this->reader->expand($basenode)) {
10011042
throw new BadMethodCallException('Unable to expand node.');
10021043
}
10031044

1004-
$doc = new DomDocument();
1005-
$node = $doc->importNode($node, true);
1045+
if ($node->ownerDocument !== $doc) {
1046+
$node = $doc->importNode($node, true);
1047+
}
10061048

10071049
return $node;
10081050
}
@@ -1089,7 +1131,7 @@ public function __get($name)
10891131
*
10901132
* @param XMLReader $reader
10911133
* @param bool $return (optional) prints by default but can return string
1092-
* @return string
1134+
* @return string|null
10931135
*/
10941136
public static function dump(XMLReader $reader, $return = FALSE)
10951137
{
@@ -1136,6 +1178,8 @@ public static function dump(XMLReader $reader, $return = FALSE)
11361178
}
11371179

11381180
printf("%s%s\n", str_repeat(' ', $reader->depth), $label);
1181+
1182+
return null;
11391183
}
11401184
}
11411185

@@ -1961,6 +2005,7 @@ function __toString() {
19612005
*/
19622006
class XMLSequenceStream
19632007
{
2008+
const DECL_POS_PATTERN = '(<\?xml\s+version\s*=\s*(["\'])(1\.\d+)\1(?:\s*\?>|\s+encoding\s*=\s*(["\'])(((?!\3).)*)\3))';
19642009
/**
19652010
* @var resource
19662011
*/
@@ -2134,8 +2179,7 @@ public function stream_read($count)
21342179

21352180
private function declPos($offset = 0)
21362181
{
2137-
$declPattern = '(<\?xml\s+version\s*=\s*(["\'])(1\.\d+)\1\s+encoding\s*=\s*(["\'])(((?!\3).)*)\3)';
2138-
$result = preg_match($declPattern, $this->reader->buffer, $matches, PREG_OFFSET_CAPTURE, $offset);
2182+
$result = preg_match(self::DECL_POS_PATTERN, $this->reader->buffer, $matches, PREG_OFFSET_CAPTURE, $offset);
21392183
if ($result === FALSE) {
21402184
throw new UnexpectedValueException('Regex failed.');
21412185
}

phpunit.xml.dist

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
colors="false"
44
bootstrap="tests/bootstrap.php"
55
>
6+
<testsuites>
7+
<testsuite name="default">
8+
<directory>tests</directory>
9+
</testsuite>
10+
</testsuites>
611
<filter>
712
<whitelist>
813
<directory>./src/</directory>

0 commit comments

Comments
 (0)