Jelajahi Sumber

Работа над XmlParser

Book Pauk 2 tahun lalu
induk
melakukan
d2484659e7
2 mengubah file dengan 31 tambahan dan 10 penghapusan
  1. 27 7
      server/core/xml/XmlParser.js
  2. 4 3
      server/core/xml/sax.js

+ 27 - 7
server/core/xml/XmlParser.js

@@ -131,6 +131,18 @@ class NodeObject extends NodeBase {
         return null;
     }
 
+    set value(v) {
+        switch (this.type) {
+            case NODE:
+                this.raw[3] = v;
+                break;
+            case TEXT:
+            case CDATA:
+            case COMMENT:
+                this.raw[1] = v;
+        }
+    }
+
     add(node, after = '*') {
         if (this.type !== NODE)
             return;
@@ -338,20 +350,28 @@ class XmlParser extends NodeBase {
         return new XmlParser(newRawNodes);
     }
 
-    s(selector, self) {
+    $$(selector, self) {
         return this.select(selector, self);
     }
 
+    $$self(selector) {
+        return this.$$(selector, true);
+    }
+
     selectFirst(selector, self) {
         const result = this.select(selector, self);
         const node = (result.count ? result.rawNodes[0] : null);
         return this.toObject(node);
     }
 
-    sf(selector, self) {
+    $(selector, self) {
         return this.selectFirst(selector, self);
     }
 
+    $self(selector) {
+        return this.$(selector, true);
+    }
+
     toJson(options = {}) {
         const {format = false} = options;
 
@@ -383,7 +403,6 @@ class XmlParser extends NodeBase {
 
             for (const n of nodes) {
                 const node = new NodeObject(n);
-                lastType = node.type;
 
                 let open = '';
                 let body = '';
@@ -412,8 +431,8 @@ class XmlParser extends NodeBase {
                     close = `</${node.name}>`;
 
                     if (format) {
-                        open = '\n' + ' '.repeat(depth) + open;
-                        close = (deepType === NODE ? ' '.repeat(depth) : '') + close + '\n';
+                        open = (lastType !== TEXT ? '\n' + ' '.repeat(depth) : '') + open;
+                        close = (deepType === NODE ? '\n' + ' '.repeat(depth) : '') + close;
                     }
                 } else if (node.type === TEXT) {
                     body = node.value || '';
@@ -424,6 +443,7 @@ class XmlParser extends NodeBase {
                 }
 
                 result += `${open}${body}${close}`;
+                lastType = node.type;
             }
 
             deepType = lastType;
@@ -437,7 +457,7 @@ class XmlParser extends NodeBase {
 
     fromString(xmlString, options = {}, pickNode = () => true) {
         const parsed = [];
-        const root = this.createNode(parsed);
+        const root = this.createNode('root', null, parsed);//fake node
         let node = root;
 
         let route = '';
@@ -460,7 +480,7 @@ class XmlParser extends NodeBase {
             if (ignoreNode)
                 return;
 
-            if (tail) {
+            if (tail && tail.trim() !== '') {
                 const parsedAttrs = sax.getAttrsSync(tail, lowerCase);
                 const attrs = new Map();
                 for (const attr of parsedAttrs.values()) {

+ 4 - 3
server/core/xml/sax.js

@@ -288,9 +288,11 @@ function getAttrsSync(tail, lowerCase = true) {
     let inName = false;
     let inValue = false;
     let waitValue = false;
-    let waitEq = false;
+    let waitEq = true;
 
     const pushResult = () => {
+        if (waitEq)
+            value = true;
         if (lowerCase)
             name = name.toLowerCase();
         if (name != '') {
@@ -308,7 +310,7 @@ function getAttrsSync(tail, lowerCase = true) {
         inName = false;
         inValue = false;
         waitValue = false;
-        waitEq = false;
+        waitEq = true;
     };
 
     tail = tail.replace(/[\t\n\r]/g, ' ');
@@ -321,7 +323,6 @@ function getAttrsSync(tail, lowerCase = true) {
                 else
                     pushResult();
             } else if (inName) {
-                waitEq = true;
                 inName = false;
             }
         } else if (!inValue && c == '=') {