Browse Source

* Merging revisions r45724 from trunk:
------------------------------------------------------------------------
r45724 | michael | 2020-07-03 21:37:41 +0200 (Fri, 03 Jul 2020) | 1 line

* Patch from Pawel Dmitruk to add CDATA and comment support
------------------------------------------------------------------------

git-svn-id: branches/fixes_3_2@46594 -

michael 5 years ago
parent
commit
467135735b
1 changed files with 75 additions and 2 deletions
  1. 75 2
      packages/fcl-xml/src/sax_xml.pp

+ 75 - 2
packages/fcl-xml/src/sax_xml.pp

@@ -31,6 +31,8 @@ type
     scUnknown,
     scWhitespace,       // within whitespace
     scText,             // within text
+    scCData,            // within cdata section
+    scComment,          // within comment
     scEntityReference,  // within entity reference ("&...;")
     scTag);             // within a start tag or end tag
 
@@ -59,7 +61,7 @@ type
 
 { TXMLToDOMConverter }
 
-  TXMLNodeType = (ntWhitespace, ntText, ntEntityReference, ntTag);
+  TXMLNodeType = (ntWhitespace, ntText, ntEntityReference, ntTag, ntComment);
 
   TXMLNodeInfo = class
     NodeType: TXMLNodeType;
@@ -77,6 +79,8 @@ type
 
     procedure ReaderCharacters(Sender: TObject; const ch: PSAXChar;
       Start, Count: Integer);
+    procedure ReaderComment(Sender: TObject; const ch: PSAXChar;
+      Start, Count: Integer);
     procedure ReaderIgnorableWhitespace(Sender: TObject; const ch: PSAXChar;
       Start, Count: Integer);
     procedure ReaderSkippedEntity(Sender: TObject; const Name: SAXString);
@@ -171,6 +175,17 @@ begin
             '<':
               begin
                 Inc(BufferPos);
+                if (Buffer[BufferPos]='!') and (Buffer[BufferPos + 1]='[') then 
+                begin
+                  Inc(BufferPos, 8);
+                  EnterNewScannerContext(scCData);
+                end
+                else if (Buffer[BufferPos]='!') and (Buffer[BufferPos + 1]='-') then 
+                begin
+                  Inc(BufferPos, 3);
+                  EnterNewScannerContext(scComment);
+                end
+                else
                 EnterNewScannerContext(scTag);
               end;
             else
@@ -191,6 +206,17 @@ begin
             '<':
               begin
                 Inc(BufferPos);
+                if (Buffer[BufferPos]='!') and (Buffer[BufferPos + 1]='[') then 
+                begin
+                  Inc(BufferPos, 8);
+                  EnterNewScannerContext(scCData);
+                end
+                else if (Buffer[BufferPos]='!') and (Buffer[BufferPos + 1]='-') then 
+                begin
+                  Inc(BufferPos, 3);
+                  EnterNewScannerContext(scComment);
+                end
+                else
                 EnterNewScannerContext(scTag);
               end;
             else
@@ -206,6 +232,17 @@ begin
             '<':
               begin
                 Inc(BufferPos);
+                if (Buffer[BufferPos]='!') and (Buffer[BufferPos + 1]='[') then 
+                begin
+                  Inc(BufferPos, 8);
+                  EnterNewScannerContext(scCData);
+                end
+                else if (Buffer[BufferPos]='!') and (Buffer[BufferPos + 1]='-') then 
+                begin
+                  Inc(BufferPos, 3);
+                  EnterNewScannerContext(scComment);
+                end
+                else
                 EnterNewScannerContext(scTag);
               end;
             else
@@ -214,6 +251,28 @@ begin
               Inc(BufferPos);
             end;
           end;
+        scCData:
+          if (Buffer[BufferPos] = ']') and (Buffer[BufferPos + 1]=']') and (Buffer[BufferPos + 2]='>') then 
+          begin
+            Inc(BufferPos, 3);
+            EnterNewScannerContext(scUnknown);
+          end
+          else
+          begin
+            FRawTokenText := FRawTokenText + Buffer[BufferPos];
+            Inc(BufferPos);
+          end;
+        scComment:
+          if (Buffer[BufferPos] = '-') and (Buffer[BufferPos + 1]='-') and (Buffer[BufferPos + 2]='>') then  
+          begin
+            Inc(BufferPos, 3);
+            EnterNewScannerContext(scUnknown);
+          end
+          else
+          begin
+            FRawTokenText := FRawTokenText + Buffer[BufferPos];
+            Inc(BufferPos);
+          end;
         scEntityReference:
           if Buffer[BufferPos] = ';' then
           begin
@@ -353,8 +412,11 @@ begin
   case ScannerContext of
     scWhitespace:
       DoIgnorableWhitespace(PSAXChar(TokenText), 0, Length(TokenText));
-    scText:
+    scText,
+    scCData:
       DoCharacters(PSAXChar(TokenText), 0, Length(TokenText));
+    scComment:
+      DoComment(PSAXChar(TokenText), 0, Length(TokenText));
     scEntityReference:
       begin
         if (Length(TokenText) >= 2) and (TokenText[1] = '#') and
@@ -459,6 +521,17 @@ begin
   FNodeBuffer.Add(NodeInfo);
 end;
 
+procedure TXMLToDOMConverter.ReaderComment(Sender: TObject;
+  const ch: PSAXChar; Start, Count: Integer);
+var
+  NodeInfo: TXMLNodeInfo;
+begin
+  NodeInfo := TXMLNodeInfo.Create;
+  NodeInfo.NodeType := ntComment;
+  NodeInfo.DOMNode := FDocument.CreateCommentBuf(ch, Count);
+  FNodeBuffer.Add(NodeInfo);
+end;
+
 procedure TXMLToDOMConverter.ReaderIgnorableWhitespace(Sender: TObject;
   const ch: PSAXChar; Start, Count: Integer);
 var