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' +HTML; + +$dom = $parser->parse($html); + +$string = $parser->invParse($dom); +echo $string; \ No newline at end of file diff --git a/examples/parse_dom_string.php b/examples/parse_dom_string.php new file mode 100644 index 0000000..8c905f7 --- /dev/null +++ b/examples/parse_dom_string.php @@ -0,0 +1,39 @@ + + + + + + + + + + + + + Hello World ! + + + + +HTML; + + +echo '
';
+$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 . '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 '
';
-$dom = $parser->setConfig([])->parse($html);
+//echo '
';
+$dom = $parser->setConfig([
+])->parse($html);
 
 print_r($dom);
\ No newline at end of file