序列化对象时省略XML处理指令
时间:2020-03-06 15:03:01 来源:igfitidea点击:
我正在CVS2003 / .Net 1.1应用程序中序列化对象。但是,我需要将其序列化而无需处理指令。 XmlSerializer类输出如下内容:
<?xml version="1.0" encoding="utf-16" ?> <MyObject> <Property1>Data</Property1> <Property2>More Data</Property2> </MyObject>
有什么办法可以得到如下内容,而无需处理结果文本来删除标记?
<MyObject> <Property1>Data</Property1> <Property2>More Data</Property2> </MyObject>
对于那些好奇的人,我的代码看起来像这样...
XmlSerializer serializer = new XmlSerializer(typeof(MyObject)); StringBuilder builder = new StringBuilder(); using ( TextWriter stringWriter = new StringWriter(builder) ) { serializer.Serialize(stringWriter, comments); return builder.ToString(); }
解决方案
在2.0中,我们将使用XmLWriterSettings.OmitXmlDeclaration,并将其序列化为XmlWriter,但是我不认为这在1.1中存在。因此,它并不完全有用,而只是"考虑升级"而已...是的,我知道这并不总是可行的。
如果通过"处理指令"表示xml声明,那么可以通过设置XmlWriterSettings的OmitXmlDeclaration属性来避免这种情况。为此,我们需要使用XmlWriter进行序列化。
XmlSerializer serializer = new XmlSerializer(typeof(MyObject)); StringBuilder builder = new StringBuilder(); XmlWriterSettings settings = new XmlWriterSettings(); settings.OmitXmlDeclaration = true; using ( XmlWriter stringWriter = new StringWriter(builder, settings) ) { serializer.Serialize(stringWriter, comments); return builder.ToString(); }
但是啊,这不能回答1.1的问题。好了,以供参考。
以下链接将带我们到一个帖子,该帖子中有人使用XmlWriter来抑制处理指令,并进入"元素"状态而非"开始"状态。这导致处理指令不被写入。
禁止处理指令
If you pass an XmlWriter to the serializer, it will only emit a processing instruction if the XmlWriter's state is 'Start' (i.e., has not had anything written to it yet).
// Assume we have a type named 'MyType' and a variable of this type named 'myObject' System.Text.StringBuilder output = new System.Text.StringBuilder(); System.IO.StringWriter internalWriter = new System.IO.StringWriter(output); System.Xml.XmlWriter writer = new System.Xml.XmlTextWriter(internalWriter); System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(MyType)); writer.WriteStartElement("MyContainingElement"); serializer.Serialize(writer, myObject); writer.WriteEndElement();
In this case, the writer will be in a state of 'Element' (inside an element) so no processing instruction will be written. One you finish writing the XML, you can extract the text from the underlying stream and process it to your heart's content.
我做了一个小更正
XmlSerializer serializer = new XmlSerializer(typeof(MyObject)); StringBuilder builder = new StringBuilder(); XmlWriterSettings settings = new XmlWriterSettings(); settings.OmitXmlDeclaration = true; using ( XmlWriter stringWriter = XmlWriter.Create(builder, settings) ) { serializer.Serialize(stringWriter, comments); return builder.ToString(); }
这适用于.NET 1.1. (但我们仍应考虑升级)
XmlSerializer s1= new XmlSerializer(typeof(MyClass)); XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add( "", "" ); MyClass c= new MyClass(); c.PropertyFromDerivedClass= "Hallo"; sw = new System.IO.StringWriter(); s1.Serialize(new XTWND(sw), c, ns); .... /// XmlTextWriterFormattedNoDeclaration /// helper class : eliminates the XML Documentation at the /// start of a XML doc. /// XTWFND = XmlTextWriterFormattedNoDeclaration public class XTWFND : System.Xml.XmlTextWriter { public XTWFND(System.IO.TextWriter w) : base(w) { Formatting = System.Xml.Formatting.Indented; } public override void WriteStartDocument() { } }
省略名称空间呢?
而不是使用
XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces(); namespaces.Add("", "");
前任:
<message xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">