* xmlwrite.pp, started implementing the streaming API.

git-svn-id: trunk@20924 -
This commit is contained in:
sergei 2012-04-19 00:21:55 +00:00
parent 3d17ae49af
commit 901eb84b3d

View File

@ -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;