From eb245de82b561193124a38f39f939e922364f65c Mon Sep 17 00:00:00 2001
From: WangFei <151241843@qq.com>
Date: Fri, 24 Apr 2020 17:48:38 +0800
Subject: [PATCH] improve the parse method and add the inverse parse
---
README.md | 31 ++++++++++++++-
examples/inverse_parse_com.php | 38 ++++++++++++++++++
examples/parse_dom_string.php | 39 ++++++++++++++++++
src/DomParser/Config.php | 22 +++++++---
src/DomParser/DomParser.php | 18 ++++++---
src/DomParser/Node.php | 73 ++++++++++++++++++++++++++++++++++
src/DomParser/Parser.php | 12 +++---
tests/DomParserTest.php | 13 +++---
8 files changed, 223 insertions(+), 23 deletions(-)
create mode 100644 examples/inverse_parse_com.php
create mode 100644 examples/parse_dom_string.php
diff --git a/README.md b/README.md
index 9df136f..559607f 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,14 @@
# dom-parser
-A PHP library , use to parse normal and special DOM string like vue react . to DOM Tree .
+A PHP library , use to parse normal and special DOM string like vue react. to DOM Tree.
+By modifying config variables, can parse other HTML-like markup languages string too.
## Installation
composer require faitheir/dom-parser
## Base Usage
-
+#### Parse Method
+parse Dom string to DOM Tree (\Faitheir\DomParser\Node $dom).
```php
$html = <<< 'HTML'
@@ -37,4 +39,29 @@ $parser = new \Faitheir\DomParser\DomParser();
$dom = $parser->setConfig([])->parse($html);
print_r($dom);
+```
+
+#### Inverse Parse Method
+parse Dom Tree(\Faitheir\DomParser\Node $dom) to DOM string.
+```php
+$string = $parser->setConfig([])->invParse($dom);
+or
+Config::getInstance()->setConfig([
+ 'tag_indent' => ' '
+]);
+$string = (string) $dom;
+```
+
+## Config Method
+```php
+# demo
+# match string '{{php id="world"}}'
+
+$configs = [
+ 'start_tag_reg' => '/^\s*{{([^}\s\/!]+)/is'
+];
+# other confs see DomPaser/Config.php
+
+$parser = $parser->setConfig($configs);
+$dom = $parser->parse($html);
```
\ No newline at end of file
diff --git a/examples/inverse_parse_com.php b/examples/inverse_parse_com.php
new file mode 100644
index 0000000..f28976f
--- /dev/null
+++ b/examples/inverse_parse_com.php
@@ -0,0 +1,38 @@
+
+
+
'; +$dom = $parser->parse($html); + +print_r($dom); \ No newline at end of file diff --git a/src/DomParser/Config.php b/src/DomParser/Config.php index 8bad547..90e0995 100644 --- a/src/DomParser/Config.php +++ b/src/DomParser/Config.php @@ -4,25 +4,37 @@ class Config { + static private $instance; + private function __clone(){} # parser configs private $_config = [ + # parse 'start_tag_reg' => '/^\s*<([^>\s\/!]+)/is', 'start_end_tag_reg' => '/(^\s*>)|(^\s*\/>)/is', 'end_tag_reg' => '/^\s*<([^>\s\/]+)/is', 'content_reg' => '/^\s*([^<]+)|()/is', 'attrs_reg' => '/^\s*([^=>< ]+)="([^"]*)"|\s([^=><\s]+)(?=\s|>)/iU', + # inverse parse + 'tag_indent' => ' ', + 'hide_genid' => false, ]; - /** - * Config constructor. - * @param array $confs - */ - public function __construct($confs = []) + private function __construct($confs = []) { if (!empty($confs)) $this->setConfig($confs); } + static public function getInstance($confs = []) + { + if (!self::$instance instanceof self) { + self::$instance = new self($confs); + } + if (!empty($confs)) + self::$instance->setConfig($confs); + + return self::$instance; + } /** * dynamic settings diff --git a/src/DomParser/DomParser.php b/src/DomParser/DomParser.php index 01935df..5b45cb2 100644 --- a/src/DomParser/DomParser.php +++ b/src/DomParser/DomParser.php @@ -1,5 +1,4 @@ config = new Config($config); + $this->config = Config::getInstance($config); $this->parser = new Parser(); if ($domString) @@ -50,7 +49,16 @@ public function parse($domString = '') if ($domString) $this->orgDomString = $domString; - return $this->parser->config($this->config)->parse($this->orgDomString); + return $this->parser->parse($this->orgDomString); } + /** + * inverse method + * @param $domTree + * @return string + */ + public function invParse(Node $domTree) + { + return (string) $domTree; + } } \ No newline at end of file diff --git a/src/DomParser/Node.php b/src/DomParser/Node.php index 5755dc1..973f03b 100644 --- a/src/DomParser/Node.php +++ b/src/DomParser/Node.php @@ -137,5 +137,78 @@ public static function generContentNode($content = '') return (new self('content'))->setNodeId()->setContent($content); } + /** + * @return string + */ + public function __toString() + { + # config + $config = Config::getInstance(); + $tagIndent = $config->get('tag_indent'); + $hideGenid = $config->get('hide_genid'); + $tagIndentString = str_repeat($tagIndent, $this->level); + + # content + if (in_array($this->nodeName, ['content'])) { + return $tagIndentString . $this->content . PHP_EOL; + } + # root + if (in_array($this->nodeName, ['root'])) { + return $this->_invParseChilds($this->childs); + } + if (empty($this->nodeName)) + return ''; + + # normal + $string = $tagIndentString . '<' . $this->nodeName . ' '; + # id + if (!empty($this->domId)) + $string .= ' id="' . $this->domId . '" '; + # gener id + if ($hideGenid == false) + $string .= ' data-genid="' . $this->nodeId . '" '; + # class + if (!empty($this->domAttrs['class'])) { + $string .= ' class="' . implode(' ', $this->domAttrs['class']) . '" '; + unset($this->domAttrs['class']); + } + # style + if (!empty($this->domAttrs['style'])) { +// $string .= implode(' ', $this->domAttrs['class']); + unset($this->domAttrs['style']); + } + # attrs + if (!empty($this->domAttrs)) { + foreach ($this->domAttrs as $k => $v) { + $string .= ' ' . $k . '="' . $v . '" '; + } + } + # is single + if ($this->isSingle == true) + return $string . ' />' . PHP_EOL; + + # start tag end + $string .= ' >' . PHP_EOL ; + + if (!empty($this->childs)) + $string .= $this->_invParseChilds($this->childs); + + # end + $string .= $tagIndentString . '' . $this->nodeName . '>' . PHP_EOL; + + return $string; + } + + private function _invParseChilds($childs) + { + if (empty($childs)) + return ''; + + $string = ''; + foreach ($childs as $child) { + $string .= (string) $child; + } + return $string; + } } \ No newline at end of file diff --git a/src/DomParser/Parser.php b/src/DomParser/Parser.php index c5447c0..0c6f36b 100644 --- a/src/DomParser/Parser.php +++ b/src/DomParser/Parser.php @@ -8,11 +8,10 @@ class Parser # config obj private $_config; - # set config obj - public function config($config = null) + # + private function _getConfig() { - $this->_config = $config; - + $this->_config = Config::getInstance(); # $this->_startTagReg = $this->_config->get('start_tag_reg'); $this->_endTagReg = $this->_config->get('end_tag_reg'); @@ -30,6 +29,9 @@ public function config($config = null) */ public function parse($domString = '') { + # init parse config + $this->_getConfig(); + $root = Node::generRootNode(); $domString = trim($domString); @@ -53,13 +55,11 @@ private function _parseChildNodes($domString = '', $parent = null) $stringLen = strlen($domString); # match start tad list($domString, $node) = $this->_parseStartTag($domString, $parent); -// $domString = $this->_parseStartTag($domString, $parent); # match content $domString = $this->_parseContent($domString, $parent); # match end tag -// $domString = $this->_parseEndTag($domString, $parent); $domString = $this->_parseEndTag($domString, $node); if ($stringLen == strlen($domString)) diff --git a/tests/DomParserTest.php b/tests/DomParserTest.php index 8422859..e9e03d2 100644 --- a/tests/DomParserTest.php +++ b/tests/DomParserTest.php @@ -8,10 +8,12 @@ $html = <<< 'HTML' - -+ + HTML; -echo '- + @@ -26,7 +28,8 @@ '; -$dom = $parser->setConfig([])->parse($html); +//echo ''; +$dom = $parser->setConfig([ +])->parse($html); print_r($dom); \ No newline at end of file