When I build a XML in C# using XmlDocument, and I want to save to XML to file, including the encoding information, I use XmlTextWriter, as below:
using (StringWriter swr = new StringWriter())
{
using (XmlTextWriter xtw = new XmlTextWriter(swr))
{
xmlDoc.WriteTo(xtw);
return swr.ToString();
}
}
With the above code, the String I get back has the following syntax:
<?xml version="1.0" encoding="utf-8"?>
<regs>
<reg1>
....
</reg1>
</regs>
I would like to have the same behavior using the IXMLDOMDocument methods. In this cenario, the only way I know to extract the XML string is through the xmlDoc.xml
method.开发者_Go百科 However, using this method, the string is quite different, as is the encoding:
<?xml version="1.0"?>
<regs>
<reg1>
....
</reg1>
</regs>
Is there a way to output a IXMLDOMDocument the same way I get with the XmlTextWriter, and with the same encoding results?
TksEdit
The code that I use to generate the XML through DOM is in Delphi:
function TXMLClass.GenerateXML: Variant;
var
iCont: Integer;
sName, sValor: String;
vXML: Variant;
oNodeDados, oNodeCliente, oNodeTransacao: Variant;
oHeader: Variant;
begin
vXML := CreateOLEObject('Msxml2.DOMDocument.6.0');
try
oHeader := vXML.createProcessingInstruction('xml', 'version=''1.0'' encoding=''utf-8''');
vXML.AppendChild(oHeader);
oNodeDados := vXML.CreateElement('regs');
vXML.AppendChild(oNodeDados);
oNodeCliente := vXML.CreateElement('reg1');
oNodeDados.AppendChild(oNodeCliente);
Result := vXML;
except
on e: Exception do
begin
vXML := Unassigned;
Result := vXML;
raise;
end;
end;
end;
My main problem is the resulting encoding of the string, because I transmit the resulting WideString to a C# WebService, and when I read it in a XmlDocument, the characters with any accent are all wrong. When I generate the XML in C#, export it through the XmlTextWriter, and send it back to Delphi, and I load it through DOM, the characters are correct.
Edit
When I use the vXML.Save(file_name.xml)
, the saved file is coded correctly, and if I load it into a WideString (Unicode string in Delphi), and transmit it to the Web Service, it works out nice. But how can I do it without saving it to disk, and through DOM?
Try passing Encoding.UTF8 as second parameter in constructor, explicitly. See http://msdn.microsoft.com/en-us/library/ms162588(v=VS.80).aspx
Have you tried using the method setOption(SXH_OPTION_URL_CODEPAGE,Encoding.UTF8)
on the root node before accessing the xml?
EDIT: Now I understand the question better. You must correctly set the encoding when you WRITE the xml string out. This is a very common problem: Setting the encoding in the XML header doesn't actually cause the output to match the declared encoding. You have to configure the writer (or whatever object writes the output stream) to actually produce UTF8.
I answered a similar question here.
With MSXML, when you save the file the encoding will be written out as well. However, when you use the xml
property the encoding will not be included. This was intentionally done by design. They designed it that way so you can turn around and call LoadXml on the string and it will work. If the encoding was included you would get an error Switch from current encoding to specified encoding not supported
. Try saving the document by calling the Save method. You will see that the encoding is included.
UPDATE:
I'm not in a place where I can test this, but the Save method can take several types of parameters. One being an object that implements the IStream interface. As such you can use the ADODB.Stream object. I don't know Delphi, so I will write out the steps to take.
- Create an instance of the ADODB.Stream object
- Set its CharSet property to "utf-8". The default is utf-16
- Call IXMLDOMDocument.Save supplying the stream oject as a parameter
- Reset the streams Position to 0, and set it's Type to adTypeText
- Call ReadText on the stream object to return the xml as a string
精彩评论