From ef5332fdca2f590032f4f7484c8dc95988e7b455 Mon Sep 17 00:00:00 2001 From: Shinbon Lin Date: Tue, 23 Feb 2016 15:40:28 +0800 Subject: [PATCH 01/13] Add Magic function __get() Add Magic function __get to make this library works like original PHP Simple Dom Parser. Now you can use like this $example->plaintext, $example->outertext, $example->innertext --- src/ParserDom.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/ParserDom.php b/src/ParserDom.php index b14d79f..837b189 100644 --- a/src/ParserDom.php +++ b/src/ParserDom.php @@ -414,7 +414,19 @@ private function clearNode(&$node) { } unset($node); } + function __get($name) + { + switch ($name) + { + case 'outertext': + return $this->outerHtml(); + case 'innertext': + return $this->innerHtml(); + case 'plaintext': + return $this->getPlainText(); + } + } } ?> From e1716784d2a8a4ed771199ab0527c381451a33fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BF=8A=E6=9D=B0Jerry?= Date: Wed, 23 Mar 2016 18:38:24 +0800 Subject: [PATCH 02/13] =?UTF-8?q?=E5=A2=9E=E5=8A=A0php7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 59a4a2e..914b5b9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,7 @@ php: - 5.4 - 5.5 - 5.6 + - 5.7 - hhvm before_script: From d38bb9f687e61932149342cb80caff1353532dfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BF=8A=E6=9D=B0Jerry?= Date: Wed, 23 Mar 2016 18:39:15 +0800 Subject: [PATCH 03/13] =?UTF-8?q?=E5=A2=9E=E5=8A=A0php7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 914b5b9..22e94fd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ php: - 5.4 - 5.5 - 5.6 - - 5.7 + - 7 - hhvm before_script: From 93fb8a5d8ac6e108cfd732cad03fca760465cb99 Mon Sep 17 00:00:00 2001 From: chenjia404 Date: Sat, 9 Apr 2016 21:08:15 +0800 Subject: [PATCH 04/13] =?UTF-8?q?=E5=A2=9E=E5=8A=A0load=E6=96=B9=E6=B3=95?= =?UTF-8?q?=EF=BC=8C=E5=8F=AF=E4=BB=A5=E5=A4=9A=E6=AC=A1=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E8=BF=99=E4=B8=AA=E5=AF=B9=E8=B1=A1=E3=80=82=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0href=E3=80=81src=E5=B1=9E=E6=80=A7=EF=BC=8C=E4=BE=BF?= =?UTF-8?q?=E4=BA=8E=E4=BD=BF=E7=94=A8=E5=87=8F=E5=B0=91PHP=20Simple=20HTM?= =?UTF-8?q?L=20DOM=20Parser=E8=BF=81=E7=A7=BB=E8=BF=87=E6=9D=A5=E7=9A=84?= =?UTF-8?q?=E6=88=90=E6=9C=AC=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ParserDom.php | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/ParserDom.php b/src/ParserDom.php index 837b189..ca8e0d5 100644 --- a/src/ParserDom.php +++ b/src/ParserDom.php @@ -42,6 +42,27 @@ public function __construct($node = null) { } } + /** + * 初始化的时候可以不用传入html,后面可以多次使用 + * @param null $node + * @throws \Exception + */ + public function load($node = null) + { + if ($node instanceof \DOMNode) { + $this->node = $node; + } else { + $dom = new \DOMDocument(); + $dom->preserveWhiteSpace = false; + $dom->strictErrorChecking = false; + if (@$dom->loadHTML($node)) { + $this->node = $dom; + } else { + throw new \Exception('load html error'); + } + } + } + /** * @codeCoverageIgnore */ @@ -424,6 +445,10 @@ function __get($name) return $this->innerHtml(); case 'plaintext': return $this->getPlainText(); + case 'href': + return $this->getAttr("href"); + case 'src': + return $this->getAttr("src"); } } From 3010bcf843d55ac2d4a51fd79f4e2406080f7ff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BF=8A=E6=9D=B0jerry?= Date: Tue, 19 Apr 2016 15:26:17 +0800 Subject: [PATCH 05/13] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1ec1c62..041c160 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ HtmlParser =============== - +[![Total Downloads](https://img.shields.io/badge/downloads-9.4k-green.svg)](https://packagist.org/packages/bupt1987/html-parser) [![Build Status](https://api.travis-ci.org/bupt1987/html-parser.svg)](https://travis-ci.org/bupt1987/html-parser) php html解析工具,类似与PHP Simple HTML DOM Parser。 From 9d30827ba56e2dc848320932a3963c1658d180d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BF=8A=E6=9D=B0Jerry?= Date: Thu, 21 Apr 2016 10:49:04 +0800 Subject: [PATCH 06/13] =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ParserDom.php | 177 +++++++++++++++------------------------------- 1 file changed, 58 insertions(+), 119 deletions(-) diff --git a/src/ParserDom.php b/src/ParserDom.php index ca8e0d5..d187ac5 100644 --- a/src/ParserDom.php +++ b/src/ParserDom.php @@ -19,20 +19,20 @@ class ParserDom { /** * @var array */ - private $_lFind = array(); + private $_lFind = []; /** * @param \DOMNode|string $node * @throws \Exception */ - public function __construct($node = null) { - if ($node !== null) { + public function __construct($node = NULL) { + if ($node !== NULL) { if ($node instanceof \DOMNode) { $this->node = $node; } else { $dom = new \DOMDocument(); - $dom->preserveWhiteSpace = false; - $dom->strictErrorChecking = false; + $dom->preserveWhiteSpace = FALSE; + $dom->strictErrorChecking = FALSE; if (@$dom->loadHTML($node)) { $this->node = $dom; } else { @@ -47,14 +47,13 @@ public function __construct($node = null) { * @param null $node * @throws \Exception */ - public function load($node = null) - { + public function load($node = NULL) { if ($node instanceof \DOMNode) { $this->node = $node; } else { $dom = new \DOMDocument(); - $dom->preserveWhiteSpace = false; - $dom->strictErrorChecking = false; + $dom->preserveWhiteSpace = FALSE; + $dom->strictErrorChecking = FALSE; if (@$dom->loadHTML($node)) { $this->node = $dom; } else { @@ -65,74 +64,32 @@ public function load($node = null) /** * @codeCoverageIgnore + * @param string $name + * @return mixed */ - public function __destruct() { - $this->clearNode($this->node); + function __get($name) { + switch ($name) { + case 'outertext': + return $this->outerHtml(); + case 'innertext': + return $this->innerHtml(); + case 'plaintext': + return $this->getPlainText(); + case 'href': + return $this->getAttr("href"); + case 'src': + return $this->getAttr("src"); + default: + return NULL; + } } /** - * 广度优先查询 - * - * @param string $selector - * @param number $idx 找第几个,从0开始计算,null 表示都返回, 负数表示倒数第几个 - * @return ParserDom|ParserDom[] + * @codeCoverageIgnore */ - /*public function findBreadthFirst($selector, $idx = null) { - if (empty($this->node->childNodes)) { - return false; - } - $selectors = $this->parse_selector($selector); - if (($count = count($selectors)) === 0) { - return false; - } - $found = array(); - for ($c = 0; $c < $count; $c++) { - if (($level = count($selectors [$c])) === 0) { - return false; - } - $need_to_search = iterator_to_array($this->node->childNodes); - $search_level = 1; - while (!empty($need_to_search)) { - $temp = array(); - foreach ($need_to_search as $search) { - if ($search_level >= $level) { - $rs = $this->seek($search, $selectors [$c], $level - 1); - if ($rs !== false && $idx !== null) { - if ($idx == count($found)) { - return new self($rs); - } else { - $found[] = new self($rs); - } - } elseif ($rs !== false) { - $found[] = new self($rs); - } - } - $temp[] = $search; - array_shift($need_to_search); - } - foreach ($temp as $temp_val) { - if (!empty($temp_val->childNodes)) { - foreach ($temp_val->childNodes as $val) { - $need_to_search[] = $val; - } - } - } - $search_level++; - } - } - if ($idx !== null) { - if ($idx < 0) { - $idx = count($found) + $idx; - } - if (isset($found[$idx])) { - return $found[$idx]; - } else { - return false; - } - } - return $found; - }*/ - + public function __destruct() { + $this->clearNode($this->node); + } /** * 深度优先查询 @@ -141,30 +98,30 @@ public function __destruct() { * @param number $idx 找第几个,从0开始计算,null 表示都返回, 负数表示倒数第几个 * @return self|self[] */ - public function find($selector, $idx = null) { + public function find($selector, $idx = NULL) { if (empty($this->node->childNodes)) { - return false; + return FALSE; } $selectors = $this->parse_selector($selector); if (($count = count($selectors)) === 0) { - return false; + return FALSE; } for ($c = 0; $c < $count; $c++) { if (($level = count($selectors [$c])) === 0) { - return false; + return FALSE; } $this->search($this->node, $idx, $selectors [$c], $level); } $found = $this->_lFind; - $this->_lFind = array(); - if ($idx !== null) { + $this->_lFind = []; + if ($idx !== NULL) { if ($idx < 0) { $idx = count($found) + $idx; } if (isset($found[$idx])) { return $found[$idx]; } else { - return false; + return FALSE; } } return $found; @@ -198,7 +155,7 @@ public function innerHtml() { */ public function outerHtml() { $doc = new \DOMDocument(); - $doc->appendChild($doc->importNode($this->node, true)); + $doc->appendChild($doc->importNode($this->node, TRUE)); return $doc->saveHTML($doc); } @@ -214,7 +171,7 @@ public function getAttr($name) { if (isset($oAttr)) { return $oAttr->nodeValue; } - return null; + return NULL; } /** @@ -243,7 +200,7 @@ private function match($exp, $pattern, $value) { } return preg_match("/" . $pattern . "/i", $value); } - return false; + return FALSE; } /** @@ -255,15 +212,15 @@ private function match($exp, $pattern, $value) { private function parse_selector($selector_string) { $pattern = '/([\w-:\*]*)(?:\#([\w-]+)|\.([\w-]+))?(?:\[@?(!?[\w-:]+)(?:([!*^$]?=)["\']?(.*?)["\']?)?\])?([\/, ]+)/is'; preg_match_all($pattern, trim($selector_string) . ' ', $matches, PREG_SET_ORDER); - $selectors = array(); - $result = array(); + $selectors = []; + $result = []; foreach ($matches as $m) { $m [0] = trim($m [0]); if ($m [0] === '' || $m [0] === '/' || $m [0] === '//') continue; if ($m [1] === 'tbody') continue; - list ($tag, $key, $val, $exp, $no_key) = array($m [1], null, null, '=', false); + list ($tag, $key, $val, $exp, $no_key) = [$m [1], NULL, NULL, '=', FALSE]; if (!empty ($m [2])) { $key = 'id'; $val = $m [2]; @@ -287,12 +244,12 @@ private function parse_selector($selector_string) { // elements that do NOT have the specified attribute if (isset ($key [0]) && $key [0] === '!') { $key = substr($key, 1); - $no_key = true; + $no_key = TRUE; } - $result [] = array($tag, $key, $val, $exp, $no_key); + $result [] = [$tag, $key, $val, $exp, $no_key]; if (trim($m [7]) === ',') { $selectors [] = $result; - $result = array(); + $result = []; } } if (count($result) > 0) { @@ -314,25 +271,25 @@ private function parse_selector($selector_string) { private function search(&$search, $idx, $selectors, $level, $search_level = 0) { if ($search_level >= $level) { $rs = $this->seek($search, $selectors, $level - 1); - if ($rs !== false && $idx !== null) { + if ($rs !== FALSE && $idx !== NULL) { if ($idx == count($this->_lFind)) { $this->_lFind[] = new self($rs); - return true; + return TRUE; } else { $this->_lFind[] = new self($rs); } - } elseif ($rs !== false) { + } elseif ($rs !== FALSE) { $this->_lFind[] = new self($rs); } } if (!empty($search->childNodes)) { foreach ($search->childNodes as $val) { if ($this->search($val, $idx, $selectors, $level, $search_level + 1)) { - return true; + return TRUE; } } } - return false; + return FALSE; } /** @@ -355,24 +312,24 @@ private function text(&$node) { */ private function seek($search, $selectors, $current) { if (!($search instanceof \DOMElement)) { - return false; + return FALSE; } list ($tag, $key, $val, $exp, $no_key) = $selectors [$current]; - $pass = true; + $pass = TRUE; if ($tag === '*' && !$key) { exit('tag为*时,key不能为空'); } if ($tag && $tag != $search->tagName && $tag !== '*') { - $pass = false; + $pass = FALSE; } if ($pass && $key) { if ($no_key) { if ($search->hasAttribute($key)) { - $pass = false; + $pass = FALSE; } } else { if ($key != "plaintext" && !$search->hasAttribute($key)) { - $pass = false; + $pass = FALSE; } } } @@ -394,7 +351,7 @@ private function seek($search, $selectors, $current) { } } if (!$check) { - $pass = false; + $pass = FALSE; } } if ($pass) { @@ -404,10 +361,10 @@ private function seek($search, $selectors, $current) { } elseif ($this->seek($this->getParent($search), $selectors, $current)) { return $search; } else { - return false; + return FALSE; } } else { - return false; + return FALSE; } } @@ -435,23 +392,5 @@ private function clearNode(&$node) { } unset($node); } - function __get($name) - { - switch ($name) - { - case 'outertext': - return $this->outerHtml(); - case 'innertext': - return $this->innerHtml(); - case 'plaintext': - return $this->getPlainText(); - case 'href': - return $this->getAttr("href"); - case 'src': - return $this->getAttr("src"); - } - } } - -?> From e16e6f09c7114386b1ea6437ec9af14e4fff6696 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BF=8A=E6=9D=B0Jerry?= Date: Thu, 21 Apr 2016 10:59:11 +0800 Subject: [PATCH 07/13] =?UTF-8?q?=E5=8F=AA=E6=94=AF=E6=8C=81php=205.5=20?= =?UTF-8?q?=E4=BB=A5=E4=B8=8A=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .travis.yml | 2 -- composer.json | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 22e94fd..2bd76a0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,6 @@ language: php php: - - 5.3 - - 5.4 - 5.5 - 5.6 - 7 diff --git a/composer.json b/composer.json index 7dc101b..808df66 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ } ], "require": { - "php": ">=5.3.2", + "php": ">=5.5", "ext-dom": "*" }, "require-dev": { From 60f207eb5259988a3fb3c400efcb1ef7c6e7b58c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BF=8A=E6=9D=B0Jerry?= Date: Thu, 21 Apr 2016 20:18:56 +0800 Subject: [PATCH 08/13] =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=86=85=E5=AD=98?= =?UTF-8?q?=E6=B8=85=E7=90=86,=20=E5=9B=A0=E4=B8=BA=E7=94=A8=E4=BA=86Dom?= =?UTF-8?q?=E6=89=A9=E5=B1=95,=E5=86=85=E5=AD=98=E9=87=8A=E6=94=BE?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=E5=B7=B2=E7=BB=8F=E8=A7=A3=E5=86=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ParserDom.php | 22 --------------------- test.php | 50 ++++++++++++++++------------------------------- 2 files changed, 17 insertions(+), 55 deletions(-) diff --git a/src/ParserDom.php b/src/ParserDom.php index d187ac5..f40b7ae 100644 --- a/src/ParserDom.php +++ b/src/ParserDom.php @@ -84,13 +84,6 @@ function __get($name) { } } - /** - * @codeCoverageIgnore - */ - public function __destruct() { - $this->clearNode($this->node); - } - /** * 深度优先查询 * @@ -378,19 +371,4 @@ private function getParent($node) { return $node->parentNode; } - /** - * @codeCoverageIgnore - * 释放内存 - * - * @param $node - */ - private function clearNode(&$node) { - if (!empty($node->childNodes)) { - foreach ($node->childNodes as $child) { - $this->clearNode($child); - } - } - unset($node); - } - } diff --git a/test.php b/test.php index 72d0fba..77d16e5 100644 --- a/test.php +++ b/test.php @@ -1,41 +1,25 @@ - - - test - - -

p1

-

p2

-

p3

-
测试1
123123
- -'; - -$html_dom = new \HtmlParser\ParserDom($html); -$p_array = $html_dom->find('p.test_class'); -$p1 = $html_dom->find('p.test_class1',0); -$div = $html_dom->find('div#test1',0); -foreach ($p_array as $p){ - echo $p->getPlainText() . "\n"; -} -echo $div->getPlainText() . "\n"; -echo $p1->getPlainText() . "\n"; -echo $p1->getAttr('class') . "\n"; - -echo "show html:\n"; -echo $div->innerHtml() . "\n"; -echo $div->outerHtml() . "\n\n"; - - $url = 'http://www.sina.com.cn/'; $sHtml = file_get_contents($url); -$oDom = new \HtmlParser\ParserDom($sHtml); -$oFound = $oDom->find('ul.uni-blk-list02', 0); +for($i = 0; $i < 10000; $i ++) { + test($sHtml); + if($i % 100 == 0) { + echo $i . ' '; + echo round(memory_get_usage() / 1024 / 1024, 3) . 'M, '; + echo round(memory_get_peak_usage() / 1024 / 1024, 3) . 'M' . "\n"; + } +} -echo "inner:\n\n" . $oFound->innerHtml() . "\n\n"; -echo "outer:\n\n" .$oFound->outerHtml() . "\n"; +echo round(memory_get_usage() / 1024 / 1024, 3) . 'M, '; +echo round(memory_get_peak_usage() / 1024 / 1024, 3) . 'M' . "\n"; +function test($sHtml) { + $oDom = new \HtmlParser\ParserDom($sHtml); + $oDom->find('ul.uni-blk-list02', 0); + $oDom->find('a'); + $oDom->find('ul'); + $oDom->find('p'); +} From a30c4fc9355acf869167cbc8a78ccb72c608d8ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BF=8A=E6=9D=B0Jerry?= Date: Fri, 19 Aug 2016 11:50:49 +0800 Subject: [PATCH 09/13] up phpunit --- composer.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 808df66..dc5e1a6 100644 --- a/composer.json +++ b/composer.json @@ -12,11 +12,10 @@ } ], "require": { - "php": ">=5.5", - "ext-dom": "*" + "php": ">=5.5" }, "require-dev": { - "phpunit/phpunit": "4.6.*" + "phpunit/phpunit": "^4.8" }, "autoload": { "psr-4": { From bba905c46b212b151de2a79a5607cb225a72180a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BF=8A=E6=9D=B0jerry?= Date: Fri, 18 Jan 2019 21:15:13 +0800 Subject: [PATCH 10/13] Update .travis.yml --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2bd76a0..944a70a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,9 @@ language: php php: - 5.5 - 5.6 - - 7 + - 7.1 + - 7.2 + - 7.3 - hhvm before_script: From ae5d325bbcf653793f65c176e1a0d2743663dcfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BF=8A=E6=9D=B0jerry?= Date: Fri, 18 Jan 2019 21:20:01 +0800 Subject: [PATCH 11/13] Update .travis.yml --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 944a70a..1bd9493 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,6 @@ php: - 7.1 - 7.2 - 7.3 - - hhvm before_script: - composer self-update From e907c223c1410fd3f4f1163f086c1b63dfc3beea Mon Sep 17 00:00:00 2001 From: XinRoom <32238570+XinRoom@users.noreply.github.com> Date: Tue, 16 Apr 2019 16:43:04 +0800 Subject: [PATCH 12/13] fix: php73 "Compilation failed" "Compilation failed: invalid range in character class at offset 3" --- src/ParserDom.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ParserDom.php b/src/ParserDom.php index f40b7ae..ac82e63 100644 --- a/src/ParserDom.php +++ b/src/ParserDom.php @@ -203,7 +203,7 @@ private function match($exp, $pattern, $value) { * @return array */ private function parse_selector($selector_string) { - $pattern = '/([\w-:\*]*)(?:\#([\w-]+)|\.([\w-]+))?(?:\[@?(!?[\w-:]+)(?:([!*^$]?=)["\']?(.*?)["\']?)?\])?([\/, ]+)/is'; + $pattern = '/([\w\-:\*]*)(?:\#([\w-]+)|\.([\w-]+))?(?:\[@?(!?[\w\-:]+)(?:([!*^$]?=)["\']?(.*?)["\']?)?\])?([\/, ]+)/is'; preg_match_all($pattern, trim($selector_string) . ' ', $matches, PREG_SET_ORDER); $selectors = []; $result = []; From 9e5fac05b9354eee16bfc84058c73c5e2b1f84a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BF=8A=E6=9D=B0jerry?= Date: Sat, 17 Aug 2019 16:35:45 +0800 Subject: [PATCH 13/13] Update .travis.yml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 只对7.2以上版本支持 --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1bd9493..42ae403 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,6 @@ language: php php: - - 5.5 - - 5.6 - - 7.1 - 7.2 - 7.3