sap*_*ket 10 c# xml serialization
我正在使用不导入缩写的空xml元素的遗留应用程序.例如:
坏空:
<foo />
Run Code Online (Sandbox Code Playgroud)
好空:
<foo></foo>
Run Code Online (Sandbox Code Playgroud)
我知道实现这一目标的解决方案,我现在将介绍:
public class XmlTextWriterFull : XmlTextWriter
{
public XmlTextWriterFull(Stream stream, Encoding enc) : base(stream, enc)
{
}
public XmlTextWriterFull(String str, Encoding enc) : base(str, enc)
{
}
public override void WriteEndElement()
{
base.WriteFullEndElement();
}
}
Run Code Online (Sandbox Code Playgroud)
和客户端代码:
var x_settings = new XmlWriterSettings();
x_settings.NewLineChars = Environment.NewLine;
x_settings.NewLineOnAttributes = true;
x_settings.NewLineHandling = NewLineHandling.Replace;
x_settings.CloseOutput = true;
x_settings.Indent = true;
x_settings.NewLineOnAttributes = true;
//var memOut = new MemoryStream();
var writer = new XmlTextWriterFull(outputFilename, Encoding.UTF8); //Or the encoding of your choice
var x_serial = new XmlSerializer(typeof(YOUR_OBJECT_TYPE));
x_serial.Serialize(writer, YOUR_OBJECT_INSTANCE);
writer.Close();
Run Code Online (Sandbox Code Playgroud)
但是,如果您仔细观察,XmlWriterSettings则从未在客户端代码中使用过.因此xml输出格式非常复杂.我的问题是这样的:我如何调整上面的代码来接受XmlWriterSettings?
工厂创建方法和密封/内部/抽象类的使用使得难以实现覆盖.
我会接受另一种解决方案,我不同意上述解决方案.
第1步:在解决方案中创建以下类:
public class XmlTextWriterFull : XmlTextWriter
{
public XmlTextWriterFull(TextWriter sink) : base(sink)
{
Formatting = Formatting.Indented;
}
public override void WriteEndElement()
{
base.WriteFullEndElement();
}
}
Run Code Online (Sandbox Code Playgroud)
第2步:添加以下客户端代码.确保将YOUR_OBJECT_TYPE和YOUR_OBJECT_INSTANCE替换为您正在使用的类和实例:
TextWriter streamWriter = new StreamWriter(outputFilename);
var writer = new XmlTextWriterFull(streamWriter);
var x_serial = new XmlSerializer(typeof (YOUR_OBJECT_TYPE));
x_serial.Serialize(writer, YOUR_OBJECT_INSTANCE);
writer.Close();
Run Code Online (Sandbox Code Playgroud)
上面的解决方法将产生以下空xml元素格式:
<foo>
</foo>
Run Code Online (Sandbox Code Playgroud)
此解决方法的问题是它添加换行符(请注意元素在单独的行上).这可能是您可以接受的,但会导致遗留应用程序出现问题.
这个怎么样.
XmlWrappingWriter从http://www.tkachenko.com/blog/archives/000585.html获取了很棒的课程(为了简洁起见,我省略了代码).
有了它,我们可以创建一个子类如下(非常类似于你原来的子类):
public class XmlTextWriterFull2 : XmlWrappingWriter
{
public XmlTextWriterFull2(XmlWriter baseWriter)
: base(baseWriter)
{
}
public override void WriteEndElement()
{
base.WriteFullEndElement();
}
}
Run Code Online (Sandbox Code Playgroud)
然后可以像这样调用它(再次非常相似):
var x_settings = new XmlWriterSettings();
x_settings.NewLineChars = Environment.NewLine;
x_settings.NewLineOnAttributes = true;
x_settings.NewLineHandling = NewLineHandling.None;
x_settings.CloseOutput = true;
x_settings.Indent = true;
x_settings.NewLineOnAttributes = true;
using (XmlWriter writer = XmlWriter.Create(outputFilename, x_settings))
{
using (XmlTextWriterFull2 xmlTextWriterFull = new XmlTextWriterFull2(writer))
{
var x_serial = new XmlSerializer(typeof(YOUR_OBJECT_TYPE));
x_serial.Serialize(xmlTextWriterFull, YOUR_OBJECT_INSTANCE);
}
}
Run Code Online (Sandbox Code Playgroud)
在我的例子中,一个先前被渲染为的元素
<Foo>
</Foo>
Run Code Online (Sandbox Code Playgroud)
成为
<Foo></Foo>
Run Code Online (Sandbox Code Playgroud)
正如你在问题中提到的那样,这实际上是一个非常棘手的问题,因为所有东西都被密封/内部等,使得覆盖相当困难.我认为我最大的问题是试图XmlWriter接受XmlWriterSettings:除了这种方法,我找不到让原件XmlTextWriterFull尊重给定的方法XmlWriterSettings.
MSDN声明这种方法:
XmlWriter.Create(XmlWriter, XmlWriterSettings)
Run Code Online (Sandbox Code Playgroud)
可用于应用XmlWriterSettings到XmlWriter.我不能像我想的那样工作(缩进从未工作过,例如),并且在反编译代码时,似乎没有所有设置都与这个特定方法一起使用,因此我的调用代码只是传入在outputFile(某种流将工作一样好).
| 归档时间: |
|
| 查看次数: |
8311 次 |
| 最近记录: |