Преглед изворни кода

* xmlread.pp, do some cleanup and get rid of FCursor field.

git-svn-id: trunk@16175 -
sergei пре 15 година
родитељ
комит
d248315ae4
1 измењених фајлова са 21 додато и 34 уклоњено
  1. 21 34
      packages/fcl-xml/src/xmlread.pp

+ 21 - 34
packages/fcl-xml/src/xmlread.pp

@@ -301,14 +301,13 @@ type
     FNext: PNodeData;
     FQName: PHashItem;
     FNodeType: TXMLNodeType;
-    FDOMNode: TObject;   // temporary
+    FDOMNode: TDOMNode_WithChildren;   // temporary
 
     FValueStr: WideString;
     FValueStart: PWideChar;
     FValueLength: Integer;
 
     // validation-specific members
-    FElement: TDOMElement;
     FElementDef: TDOMElementDef;
     FCurCP: TContentParticle;
     FFailed: Boolean;
@@ -412,7 +411,6 @@ type
     procedure CleanupAttributeData;
     procedure SetNodeInfoWithValue(typ: TXMLNodeType; AName: PHashItem = nil);
   protected
-    FCursor: TDOMNode_WithChildren;
     FNesting: Integer;
     FCurrNode: PNodeData;
     FAttrCount: Integer;
@@ -450,7 +448,7 @@ type
     procedure ParseMarkupDecl;                                          // [29]
     procedure ParseStartTag;                                            // [39]
     procedure ParseEndTag;                                              // [42]
-    procedure DoEndElement(ErrOffset: Integer);
+    procedure DoEndElement;
     procedure ParseAttribute(Elem: TDOMElement; ElDef: TDOMElementDef);
     procedure ParseContent;                                             // [43]
     function  Read: Boolean;
@@ -1372,7 +1370,6 @@ procedure TXMLReader.ProcessXML(ASource: TXMLCharSource);
 begin
   doc := TXMLDocument.Create;
   doc.documentURI := ASource.SystemID;  // TODO: to be changed to URI or BaseURI  
-  FCursor := doc;
   FState := rsProlog;
   FNesting := 0;
   FCurrNode := @FNodeStack[0];
@@ -1390,11 +1387,10 @@ end;
 procedure TXMLReader.ProcessFragment(ASource: TXMLCharSource; AOwner: TDOMNode);
 begin
   doc := AOwner.OwnerDocument;
-  FCursor := AOwner as TDOMNode_WithChildren;
   FState := rsRoot;
   FNesting := 0;
   FCurrNode := @FNodeStack[0];
-  FCurrNode^.FDOMNode := FCursor;
+  FCurrNode^.FDOMNode := AOwner as TDOMNode_WithChildren;
   FXML11 := doc.InheritsFrom(TXMLDocument) and (TXMLDocument(doc).XMLVersion = '1.1');
   Initialize(ASource);
   FDocType := TDOMDocumentTypeEx(doc.DocType);
@@ -2008,7 +2004,7 @@ begin
     ValidationError('Processing instructions are not allowed within EMPTY elements', []);
 
   PINode := Doc.CreateProcessingInstruction(NameStr, ValueStr);
-  FCursor.AppendChild(PINode)
+  FNodeStack[FNesting].FDOMNode.InternalAppend(PINode);
 end;
 
 const
@@ -2710,7 +2706,6 @@ begin
   doc := TXMLDocument.Create;
   FDocType := TDOMDocumentTypeEx.Create(doc);
   // TODO: DTD labeled version 1.1 will be rejected - must set FXML11 flag
-  // DONE: It's ok to have FCursor=nil now
   doc.AppendChild(FDocType);
   Initialize(ASource);
   ParseMarkupDecl;
@@ -2796,7 +2791,7 @@ begin
       xtComment:
         DoComment(FCurrNode^.FValueStart, FCurrNode^.FValueLength);
       xtEndElement:
-        DoEndElement(-1);
+        DoEndElement;
       xtDoctype:
         if not FCanonical then
         begin
@@ -2898,7 +2893,7 @@ begin
       if InCDATA then
         FatalError('Unterminated CDATA section', -1);
       if FNesting > FSource.FStartNesting then
-        FatalError('End-tag is missing for ''%s''', [FCurrNode^.FElement.NSI.QName^.Key]);
+        FatalError('End-tag is missing for ''%s''', [FNodeStack[FNesting].FQName^.Key]);
       if ContextPop then Continue;
       tok := xtEOF;
     end
@@ -2966,14 +2961,9 @@ begin
   FNext := xtText;
 
   case tok of
-    xtEntity:     AppendReference(FCursor, FCurrEntity);
+    xtEntity:     AppendReference(FNodeStack[FNesting].FDOMNode, FCurrEntity);
     xtElement:    ParseStartTag;
-    xtEndElement:
-      begin
-        ParseEndTag;
-        FCurrNode^.FNodeType := ntEndElement;
-        FNext := xtPopElement;
-      end;
+    xtEndElement: ParseEndTag;
     xtPI:         ParsePI;
     xtDoctype:    ParseDoctypeDecl;
     xtComment:    ParseComment(False);
@@ -3013,13 +3003,14 @@ begin
     FState := rsRoot;
   end;
 
-  NewElem := doc.CreateElementBuf(FName.Buffer, FName.Length);
-  FCursor.AppendChild(NewElem);
   // we're about to process a new set of attributes
   Inc(FAttrTag);
   // can point to a child text/comment/PI node, so restore it
   FCurrNode := @FNodeStack[FNesting];
 
+  NewElem := doc.CreateElementBuf(FName.Buffer, FName.Length);
+  FCurrNode^.FDOMNode.InternalAppend(NewElem);
+
   // Remember the hash entry, we'll need it often
   ElName := NewElem.NSI.QName;
 
@@ -3063,7 +3054,6 @@ begin
 
   if not IsEmpty then
   begin
-    FCursor := NewElem;
     if not FPreserveWhitespace then   // critical for testsuite compliance
       SkipS;
     FNext := xtPushElement;
@@ -3072,18 +3062,13 @@ begin
     FNext := xtPopEmptyElement;
 end;
 
-procedure TXMLReader.DoEndElement(ErrOffset: Integer);
-var
-  NewElem: TDOMElement;
+procedure TXMLReader.DoEndElement;
 begin
-  NewElem := FCurrNode^.FElement;
-  TDOMNode(FCursor) := NewElem.ParentNode;
-  if FCursor = doc then
+  if (FNesting > 0) and (FNodeStack[FNesting-1].FDOMNode = doc) then
     FState := rsEpilog;
 
   if FValidate and FCurrNode^.Incomplete then
-    ValidationError('Element ''%s'' is missing required sub-elements', [NewElem.NSI.QName^.Key], ErrOffset);
-
+    ValidationError('Element ''%s'' is missing required sub-elements', [FNodeStack[FNesting].FQName^.Key], -1);
 end;
 
 procedure TXMLReader.ParseEndTag;     // [42]
@@ -3095,6 +3080,7 @@ begin
   Inc(FSource.FBuf);
 
   FCurrNode := @FNodeStack[FNesting];  // move off the possible child
+  FCurrNode^.FNodeType := ntEndElement;
   ElName := FCurrNode^.FQName;
 
   CheckName;
@@ -3108,6 +3094,7 @@ begin
     ExpectChar('>');
   end;
   Inc(FTokenStart.LinePos, 2);   // move over '</' chars
+  FNext := xtPopElement;
 end;
 
 procedure TXMLReader.ParseAttribute(Elem: TDOMElement; ElDef: TDOMElementDef);
@@ -3477,7 +3464,7 @@ begin
 
   // Document builder part
   TextNode := Doc.CreateTextNodeBuf(ch, Count, Whitespace and (FCurrContentType = ctChildren));
-  FCursor.AppendChild(TextNode);
+  FNodeStack[FNesting].FDOMNode.InternalAppend(TextNode);
 end;
 
 procedure TXMLReader.DoComment(ch: PWideChar; Count: Integer);
@@ -3489,10 +3476,10 @@ begin
     ValidationError('Comments are not allowed within EMPTY elements', []);
 
   // DOM builder part
-  if (not FIgnoreComments) and Assigned(FCursor) then
+  if (not FIgnoreComments) and (FState <> rsDTD) then
   begin
     Node := Doc.CreateCommentBuf(ch, Count);
-    FCursor.AppendChild(Node);
+    FNodeStack[FNesting].FDOMNode.InternalAppend(Node);
   end;
 end;
 
@@ -3506,7 +3493,7 @@ begin
     ValidationError('CDATA sections are not allowed in element-only content',[]);
 
   SetString(s, ch, Count);
-  FCursor.AppendChild(doc.CreateCDATASection(s));
+  FNodeStack[FNesting].FDOMNode.InternalAppend(doc.CreateCDATASection(s));
 end;
 
 procedure TXMLReader.DoNotationDecl(const aName, aPubID, aSysID: WideString);
@@ -3593,7 +3580,7 @@ procedure TXMLReader.PushVC(aElement: TDOMElement; aElDef: TDOMElementDef);
 begin
   Inc(FNesting);
   FCurrNode := AllocNodeData(FNesting);
-  FCurrNode^.FElement := aElement;
+  FCurrNode^.FDOMNode := aElement;
   FCurrNode^.FElementDef := aElDef;
   FCurrNode^.FCurCP := nil;
   FCurrNode^.FFailed := False;