EldoS | Feel safer!

Software components for data protection, secure storage and transfer

How to expor xml content of TXMLDocument into TElXMLDOMDocument

Also by EldoS: CallbackProcess
A component to control process creation and termination in Windows and .NET applications.
#26452
Posted: 09/16/2013 10:21:02
by Jacob jvandiermen (Standard support level)
Joined: 08/09/2013
Posts: 55

Hello Eldos,

I have a TXMLDocument document object. I want to export the content of this object to a TElXMLDOMDocument object;

Tried the following:

xmlDocument:= TXMLDocument.Create(nil);
xmlDOMDocument:= TElXMLDOMDocument.Create();
memoryStream: TMemoryStream;

xmlString:= xmlDocument.XML.Text;
memoryStream:= TMemoryStream.Create();
memoryStream.WriteBuffer(Pointer(xmlString)^, Length(xmlString));
memoryStream.Position:= 0;
xmlDomDocument.LoadFromStream(memoryStream,'utf-8', true);

But LoadFromStream procedure doesn't work. I get an EElXMLEncoding error Invalid char.

What is the best way to do this?
A work around is to first save the xmlDocument to a file on disk and then use a filestreamer to load the file in xmlDomDocument.

Regards,

Jacob
#26455
Posted: 09/16/2013 10:54:19
by Dmytro Bogatskyy (EldoS Corp.)

Thank you for contacting us.

Quote
xmlString:= xmlDocument.XML.Text;

Why not to save xml document using SaveToStream method?
Quote
xmlDomDocument.LoadFromStream(memoryStream,'utf-8', true);

But LoadFromStream procedure doesn't work. I get an EElXMLEncoding error Invalid char.

Are you using Unicode Delphi (2009 or higher)?
#26456
Posted: 09/16/2013 10:56:42
by Eugene Mayevski (EldoS Corp.)

Quote
Jacob jvandiermen wrote:
memoryStream.WriteBuffer(Pointer(xmlString)^, Length(xmlString));


I don't think this is correct typecast. I would write

Code
memoryStream.WriteBuffer(xmlString[1], Length(xmlString));


On a side note, please use CODE tag or CODE button to mark your code blocks.


Sincerely yours
Eugene Mayevski
#26489
Posted: 09/17/2013 05:55:08
by Jacob jvandiermen (Standard support level)
Joined: 08/09/2013
Posts: 55

Hallo Eugene Mayevski,

Yes I'm using unicode Delphi 2010.
The source code for filling the memoryStream works fine!
stringValue is a string that contains a valid xml.
I fill stringValue with the property XML.Text of the TElXMLDOMDocument object.
The value of stringValue is:

Code
'<?xml version="1.0"?>'#$D#$A'<dsig:Signature xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" Id="Signature001"><dsig:SignedInfo><dsig:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/><dsig:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><dsig:Reference Id="#KeyInfo001"><dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><dsig:DigestValue>'#9'</dsig:DigestValue></dsig:Reference><dsig:Reference URI="#Resource1"><dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><dsig:DigestValue>'#9'</dsig:DigestValue></dsig:Reference></dsig:SignedInfo><dsig:SignatureValue>'#9'</dsig:SignatureValue><dsig:KeyInfo Id="KeyInfo001"><X509Data><X509SubjectName>'#9'</X509SubjectName><X509Certificate>'#9'</X509Certificate></X509Data><dsig:KeyValue><dsig:RSAKeyValue><dsig:Modulus>'#9'</dsig:Modulus><dsig:Exponent>'#9'</dsig:Exponent></dsig:RSAKeyValue></dsig:KeyValue></dsig:KeyInfo><dsig:Object>'#9'</dsig:Object></dsig:Signature>'#$D#$A


Code
size:= Length(stringValue);
memoryStream:= TMemoryStream.Create();
memoryStream.WriteBuffer(Pointer(stringValue)^,size);
memoryStream.Position:= 0;
// Retrieve thte string value back to make sure it worked.
stringValue:= '';
// Set the length, so we have space to read into
SetLength(stringValue, memoryStream.Size);
memoryStream.ReadBuffer(Pointer(stringValue)^,memoryStream.Size);


But you can replace
Code
  
memoryStream.WriteBuffer(Pointer(stringValue)^,size);

with
Code
memoryStream.WriteBuffer(xmlString[1], Length(xmlString));

And also
Code

memoryStream.ReadBuffer(Pointer(stringValue)^,memoryStream.Size);

with
Code
memoryStream.ReadBuffer(xmlString[1], Length(xmlString));

And everything works just great.

When I use the method SaveToStream of the TElXMLDOMDocument object and try to retrieve the string value back from memoryStream, the string value is scrambled.That is way i use the TMemoryStream.

When i want to use the memoryStream in the method LoadFromStream of my TElXMLDOMDocument object I get the Error Invalid Char!

How can I load the memorystream content, which is a valid xml into the the TElXMLDOMDocument object? Or Is there a other way?

Regards,

Jacob
#26490
Posted: 09/17/2013 05:59:49
by Vsevolod Ievgiienko (EldoS Corp.)

Hello.

Try to convert the string into UTF-8 before you write it into TMemoryStream using SBStrUtils.SrtToUTF8 function.
#26491
Posted: 09/17/2013 06:14:54
by Dmytro Bogatskyy (EldoS Corp.)

Hello,

Quote
When I use the method SaveToStream of the TElXMLDOMDocument objectand try to retrieve the string value back from memoryStream, the string value is scrambled.That is way i use the TMemoryStream.

TElXMLDOMDocument or TXMLDocument?

Quote
memoryStream.WriteBuffer(xmlString[1], Length(xmlString));

In case if you are using Delphi 2010 this code should be
Code
memoryStream.WriteBuffer(xmlString[1], Length(xmlString) * SizeOf(Char));


Quote
How can I load the memorystream content, which is a valid xml into the the TElXMLDOMDocument object? Or Is there a other way?

In your case a MemoryStream object contains UTF-16 encoded data, it doesn't contain BOM mark, so we can't automatically detect the encoding. So you should use 'utf-16' for a default encoding:
Code
xmlDomDocument.LoadFromStream(memoryStream,'utf-16', true);
#26499
Posted: 09/17/2013 09:16:59
by Jacob jvandiermen (Standard support level)
Joined: 08/09/2013
Posts: 55

Hello Dmytro Bogatskyy,

I managed to port the xml content from a TXMLDocument object into a TElXMLDOMDocument object. Thanks for your code!
Also thanks to Eugene Mayevski and Vsevolod Ievgiienko for helping me.

Regards,

Jacob
Also by EldoS: CallbackProcess
A component to control process creation and termination in Windows and .NET applications.

Reply

Statistics

Topic viewed 1750 times

Number of guests: 1, registered members: 0, in total hidden: 0




|

Back to top

As of July 15, 2016 EldoS Corporation will operate as a division of /n software inc. For more information, please read the announcement.

Got it!