while not Terminated dotry
Data := Parent.IdTCPClient.IOHandler.ReadLn(IndyTextEncoding_UTF8);
if Length(Data) > 0 then
on E: EIdException do
Error := E.Message;
Please, help fix it! How can I read XML data correctly?
Mar 20, 2017 11:36 AM
in response to: Oleg Skok
I try to add simple XMPP-client in my project, where I use idTCPClient
already. When I receive XML package from server, I can't parse it,
because it's broken.
The XML is not "broken", you are simply not reading it from the socket correctly
to begin with. You are assuming complete "messages" are (CR)LF delimited,
and that is not the case (read the XMPP specifications! RFC 6120 in perticular).
In XML, (CR)LF is just ignorable whitespace, not an end-of-data delimiter,
so your use of the IOHandler.ReadLn() method is just plain wrong in this
Please, help fix it!
You need to re-write your socket reading logic. There is no delimiter between
"messages", so you have to parse the XML while you are reading it from the
socket. Starting at a depth of 1, you have to recognize where one XML element
ends and the next begins so you can increment the depth counter for each
opening tag and decrement it for each closing tag, until you reach the closing
tag at depth 1. Only then will you have received a complete "message" and
can process it as needed.
This would be best handled using an XML parser that supports a pushing model
for input. You can then use the IOHandler.ReadBytes() method to read arbitrary
bytes off of the socket and "push" them into the XML engine, and let it give
you events when it has parsed completed XML elements, giving you the element
name, attributes, depth, etc.
Delphi's native XML framework does not support this kind of parsing, but
plenty of 3rd party XML engines do.