views:

56

answers:

3

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. 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?
Tks

Edit

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?

A: 

Try passing Encoding.UTF8 as second parameter in constructor, explicitly. See http://msdn.microsoft.com/en-us/library/ms162588(v=VS.80).aspx

djechelon
My problem is not doing it with the XmlTextWriter (it works great), but to get the same output through the XML DOM. But tks
Pascal
A: 

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.

Jim Garrison
I posted the code that generates the DOM XML, but I don't think the setOption will solve my problem. But tks for your time
Pascal
Yes, exactly... sorry if I've phrased it wrong. My question is how do I do this with DOM? Tks
Pascal
A: 

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
Garett
Garrett, with the Save, it works perfect, but then I have to save to disk, and load the file to a WideString in Dlephi, and then transmit it through the WebService, so it is loaded correctly inside it using LoadXML. How can I do this without saving it to disk, and through DOM? Tks for your time
Pascal
Garett, as it turned out, the problem wasn't actually on the saving the XML part... it was on the transmitting to the C# web service part (post http://stackoverflow.com/questions/3902259/soap-envelope-header-in-delphi-7-not-including-utf-8-encoding-how-can-i-modify-i/3903679#3903679). Tks for your time
Pascal