From 901eb84b3d847ecbe802501f686c5e75365da9fa Mon Sep 17 00:00:00 2001 From: sergei <gorelkin@nanoreflex.ru> Date: Thu, 19 Apr 2012 00:21:55 +0000 Subject: [PATCH] * xmlwrite.pp, started implementing the streaming API. git-svn-id: trunk@20924 - --- packages/fcl-xml/src/xmlwrite.pp | 105 +++++++++++++++++++------------ 1 file changed, 66 insertions(+), 39 deletions(-) diff --git a/packages/fcl-xml/src/xmlwrite.pp b/packages/fcl-xml/src/xmlwrite.pp index ab9d8d2f61..52209d1cee 100644 --- a/packages/fcl-xml/src/xmlwrite.pp +++ b/packages/fcl-xml/src/xmlwrite.pp @@ -81,14 +81,19 @@ type procedure VisitDocument(Node: TDOMNode); procedure VisitDocument_Canonical(Node: TDOMNode); procedure VisitElement(Node: TDOMNode); - procedure VisitText(Node: TDOMNode); - procedure VisitCDATA(Node: TDOMNode); - procedure VisitComment(Node: TDOMNode); + procedure WriteString(const Text: XMLString); + procedure WriteCDATA(const Text: XMLString); + procedure WriteComment(const Text: XMLString); procedure VisitFragment(Node: TDOMNode); procedure VisitAttribute(Node: TDOMNode); procedure VisitEntityRef(Node: TDOMNode); procedure VisitDocumentType(Node: TDOMNode); procedure VisitPI(Node: TDOMNode); + + procedure WriteProcessingInstruction(const Target, Data: XMLString); + procedure WriteEntityRef(const Name: XMLString); + procedure WriteAttributeString(const Name, Value: XMLString); + procedure WriteDocType(const Name, PubId, SysId, Subset: XMLString); public constructor Create(AStream: TStream; ANameTable: THashTable); destructor Destroy; override; @@ -401,11 +406,11 @@ begin case node.NodeType of ELEMENT_NODE: VisitElement(node); ATTRIBUTE_NODE: VisitAttribute(node); - TEXT_NODE: VisitText(node); - CDATA_SECTION_NODE: VisitCDATA(node); + TEXT_NODE: WriteString(TDOMCharacterData(node).Data); + CDATA_SECTION_NODE: WriteCDATA(TDOMCharacterData(node).Data); ENTITY_REFERENCE_NODE: VisitEntityRef(node); PROCESSING_INSTRUCTION_NODE: VisitPI(node); - COMMENT_NODE: VisitComment(node); + COMMENT_NODE: WriteComment(TDOMCharacterData(node).Data); DOCUMENT_NODE: if FCanonical then VisitDocument_Canonical(node) @@ -615,52 +620,62 @@ begin FNSHelper.PopScope; end; -procedure TXMLWriter.VisitText(node: TDOMNode); +procedure TXMLWriter.WriteString(const Text: XMLString); begin - ConvWrite(TDOMCharacterData(node).Data, TextSpecialChars, TextnodeCallbacks[FCanonical]); + ConvWrite(Text, TextSpecialChars, TextnodeCallbacks[FCanonical]); end; -procedure TXMLWriter.VisitCDATA(node: TDOMNode); +procedure TXMLWriter.WriteCDATA(const Text: XMLString); begin if not FInsideTextNode then wrtIndent; if FCanonical then - ConvWrite(TDOMCharacterData(node).Data, TextSpecialChars, @TextnodeCanonicalCallback) + ConvWrite(Text, TextSpecialChars, @TextnodeCanonicalCallback) else begin wrtChars('<![CDATA[', 9); - ConvWrite(TDOMCharacterData(node).Data, CDSectSpecialChars, @CDSectSpecialCharCallback); + ConvWrite(Text, CDSectSpecialChars, @CDSectSpecialCharCallback); wrtChars(']]>', 3); end; end; -procedure TXMLWriter.VisitEntityRef(node: TDOMNode); +procedure TXMLWriter.WriteEntityRef(const Name: XMLString); begin wrtChr('&'); - wrtStr(node.NodeName); + wrtStr(Name); wrtChr(';'); end; -procedure TXMLWriter.VisitPI(node: TDOMNode); +procedure TXMLWriter.VisitEntityRef(node: TDOMNode); +begin + WriteEntityRef(node.NodeName); +end; + +procedure TXMLWriter.WriteProcessingInstruction(const Target, Data: XMLString); begin if not FInsideTextNode then wrtIndent; wrtStr('<?'); - wrtStr(TDOMProcessingInstruction(node).Target); - if TDOMProcessingInstruction(node).Data <> '' then + wrtStr(Target); + if Data <> '' then begin wrtChr(' '); // TODO: How does this comply with c14n?? - ConvWrite(TDOMProcessingInstruction(node).Data, LineEndingChars, @TextnodeNormalCallback); + ConvWrite(Data, LineEndingChars, @TextnodeNormalCallback); end; wrtStr('?>'); end; -procedure TXMLWriter.VisitComment(node: TDOMNode); +procedure TXMLWriter.VisitPI(node: TDOMNode); +begin + WriteProcessingInstruction(TDOMProcessingInstruction(node).Target, TDOMProcessingInstruction(node).Data); +end; + +procedure TXMLWriter.WriteComment(const Text: XMLString); begin if not FInsideTextNode then wrtIndent; wrtChars('<!--', 4); // TODO: How does this comply with c14n?? - ConvWrite(TDOMCharacterData(node).Data, LineEndingChars, @TextnodeNormalCallback); + ConvWrite(Text, LineEndingChars, @TextnodeNormalCallback); wrtChars('-->', 3); end; @@ -738,6 +753,15 @@ begin end; end; +procedure TXMLWriter.WriteAttributeString(const Name, Value: XMLString); +begin + wrtChr(' '); + wrtStr(Name); + wrtChars('="', 2); + ConvWrite(Value, AttrSpecialChars, {$IFDEF FPC}@{$ENDIF}AttrSpecialCharCallback); + wrtChr('"'); +end; + procedure TXMLWriter.VisitAttribute(Node: TDOMNode); var Child: TDOMNode; @@ -760,31 +784,34 @@ begin end; procedure TXMLWriter.VisitDocumentType(Node: TDOMNode); +begin + WriteDocType(Node.NodeName, TDOMDocumentType(Node).PublicID, TDOMDocumentType(Node).SystemID, + TDOMDocumentType(Node).InternalSubset); +end; + +procedure TXMLWriter.WriteDocType(const Name, PubId, SysId, Subset: XMLString); begin wrtStr(FLineBreak); wrtStr('<!DOCTYPE '); - wrtStr(Node.NodeName); + wrtStr(Name); wrtChr(' '); - with TDOMDocumentType(Node) do + if PubId <> '' then begin - if PublicID <> '' then - begin - wrtStr('PUBLIC '); - wrtQuotedLiteral(PublicID); - wrtChr(' '); - wrtQuotedLiteral(SystemID); - end - else if SystemID <> '' then - begin - wrtStr('SYSTEM '); - wrtQuotedLiteral(SystemID); - end; - if InternalSubset <> '' then - begin - wrtChr('['); - ConvWrite(InternalSubset, LineEndingChars, @TextnodeNormalCallback); - wrtChr(']'); - end; + wrtStr('PUBLIC '); + wrtQuotedLiteral(PubId); + wrtChr(' '); + wrtQuotedLiteral(SysId); + end + else if SysId <> '' then + begin + wrtStr('SYSTEM '); + wrtQuotedLiteral(SysId); + end; + if Subset <> '' then + begin + wrtChr('['); + ConvWrite(Subset, LineEndingChars, @TextnodeNormalCallback); + wrtChr(']'); end; wrtChr('>'); end;