EldoS | Feel safer!

Software components for data protection, secure storage and transfer

How to expor xml content of TXMLDocument into TElXMLDOMDocument

Also by EldoS: CallbackFilter
A component to monitor and control disk activity, track file and directory operations (create, read, write, rename etc.), alter file data, encrypt files, create virtual files.
#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: Callback File System
Create virtual file systems and disks, expose and manage remote data as if they were files on the local disk.

Reply

Statistics

Topic viewed 1742 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!