简体   繁体   English

与XmlTextWriter一样保存XML,但带有DOM

[英]Save XML like XmlTextWriter but with DOM

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: 当我使用XmlDocument在C#中构建XML并想保存到XML到文件中,包括编码信息时,我使用XmlTextWriter,如下所示:

    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: 通过上面的代码,我得到的String具有以下语法:

<?xml version="1.0" encoding="utf-8"?>
<regs>
  <reg1>
....
  </reg1>
</regs>

I would like to have the same behavior using the IXMLDOMDocument methods. 我希望使用IXMLDOMDocument方法具有相同的行为。 In this cenario, the only way I know to extract the XML string is through the xmlDoc.xml method. 在这种情况下,我知道提取XML字符串的xmlDoc.xml方法是通过xmlDoc.xml方法。 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? 有没有一种方法可以输出与XmlTextWriter相同的IXMLDOMDocument,并具有相同的编码结果?
Tks ks

Edit 编辑

The code that I use to generate the XML through DOM is in Delphi: 我用于通过DOM生成XML的代码在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. 我的主要问题是字符串的结果编码,因为我将结果WideString传输到C#WebService,并且当我在XmlDocument中读取它时,带有重音符号的字符都是错误的。 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. 当我用C#生成XML时,通过XmlTextWriter将其导出,然后将其发送回Delphi,然后通过DOM加载,这些字符是正确的。

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. 当我使用vXML.Save(file_name.xml) ,已保存的文件已正确编码,并且如果将其加载到WideString(Delphi中的Unicode字符串)中并将其传输到Web服务,则效果很好。 But how can I do it without saving it to disk, and through DOM? 但是,如何在不将其保存到磁盘以及通过DOM的情况下做到这一点呢?

Try passing Encoding.UTF8 as second parameter in constructor, explicitly. 尝试将Encoding.UTF8作为显式构造函数中的第二个参数传递。 See http://msdn.microsoft.com/en-us/library/ms162588(v=VS.80).aspx 参见http://msdn.microsoft.com/zh-cn/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? 您是否曾尝试在访问xml之前在根节点上使用方法setOption(SXH_OPTION_URL_CODEPAGE,Encoding.UTF8)

EDIT: Now I understand the question better. 编辑:现在我更好地理解了这个问题。 You must correctly set the encoding when you WRITE the xml string out. 当您写出xml字符串时,必须正确设置编码。 This is a very common problem: Setting the encoding in the XML header doesn't actually cause the output to match the declared encoding. 这是一个非常常见的问题:在XML标头中设置编码实际上并不会导致输出与声明的编码匹配。 You have to configure the writer (or whatever object writes the output stream) to actually produce UTF8. 您必须配置writer(或任何写入输出流的对象)才能实际产生UTF8。

I answered a similar question here . 在这里回答了类似的问题。

With MSXML, when you save the file the encoding will be written out as well. 使用MSXML,当您保存文件时,编码也将被写出。 However, when you use the xml property the encoding will not be included. 但是,当您使用xml属性时,将不包含编码。 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. 他们以这种方式设计了它,以便您可以转过头并在字符串上调用LoadXml ,它将起作用。 If the encoding was included you would get an error Switch from current encoding to specified encoding not supported . 如果包含了编码,则会出现错误, Switch from current encoding to specified encoding not supported Try saving the document by calling the Save method. 尝试通过调用Save方法保存文档。 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. 我不在可以测试这一点的地方,但是Save方法可以使用几种类型的参数。 One being an object that implements the IStream interface. 一个是实现IStream接口的对象。 As such you can use the ADODB.Stream object. 这样,您可以使用ADODB.Stream对象。 I don't know Delphi, so I will write out the steps to take. 我不认识Delphi,所以我会写下要采取的步骤。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM