如何使用覆盖无效对writeEndElement时使用XmlWriterSettings()()? [英] How to use XmlWriterSettings() when using override void WriteEndElement()?

查看:261
本文介绍了如何使用覆盖无效对writeEndElement时使用XmlWriterSettings()()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我与不导入简称空XML元素的遗留应用程序的工作。例如:

I am working with a legacy application that does not import abbreviated empty xml elements. For example:

BAD空的:

<foo />



GOOD空的:

GOOD empty:

<foo></foo>



我知道解决的办法实现这一目标,我将现在提出:

I know the solution to achieve this, which I will present now:

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();
    }
}

和客户端代码:

                    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();



然而,如果你观察仔细的 XmlWriterSettings 从未在客户代码中使用。因此,XML输出​​非常格式化。我的问题是这样的:我怎么适应上面的代码来接受 XmlWriterSettings

However, if you observed carefully the XmlWriterSettings are never used in the client code. Therefore the xml output is terribly formatted. My questions is this: how do I adapt the above code to accept XmlWriterSettings?

采用工厂创建方法和密封/内部/抽象类使这难以实施一个覆盖。

The use of factory creation methods and sealed/internal/abstract classes makes this difficult to implement an override.

我会接受的替代解决方案,我没有结婚,我上面的解决方案。

I will accept an alternative solution, I am not married to my above solution.


  • 替代方法解决方案

第1步:创建解决方案中的以下类:

Step 1: create the following class in your solution:

public class XmlTextWriterFull : XmlTextWriter
{
    public XmlTextWriterFull(TextWriter sink) : base(sink)
    {
        Formatting = Formatting.Indented;
    }

    public override void WriteEndElement()
    {
        base.WriteFullEndElement();
    }
}



第2步:添加下面的客户端代码。确保与类和实例您正在使用替代YOUR_OBJECT_TYPE和YOUR_OBJECT_INSTANCE:

Step 2: Add the following client code. Make sure to replace YOUR_OBJECT_TYPE and YOUR_OBJECT_INSTANCE with the class and instance your are working with:

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();



解决方法上面将产生以下空XML元素格式:

The workaround above will produce the following empty xml element formatting:

<foo>
</foo>



这个解决办法的问题是,它增加了一个换行符(注意元素是在单独的行) 。这可能是你可以接受的,但会导致我的旧应用程序的问题。

The issue with this workaround is that it adds a line feed (notice the elements are on separate lines). This may be acceptable for you but causes issues with my legacy application.

推荐答案

这个怎么样。

从抢的 XmlWrappingWriter 类相对=nofollow> http://www.tkachenko.com/blog/archives/000585.html (Ⅰ省略为简洁起见,代码)。

Grab the awesome XmlWrappingWriter class from http://www.tkachenko.com/blog/archives/000585.html (I have omitted the code for the sake of brevity).

通过这一点,我们可以按照如下(非常类似于原来的一个)创建一个子类:

With that, we can create a sub-class as follows (very similar to your original one):

public class XmlTextWriterFull2 : XmlWrappingWriter
{
    public XmlTextWriterFull2(XmlWriter baseWriter)
        : base(baseWriter)
    {
    }

    public override void WriteEndElement()
    {
        base.WriteFullEndElement();
    }
}



然后它可以调用像这样(再次非常相似):

It can then be invoked like this (again very similar):

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);
    }
}

在我的情况下,以前被渲染的元素为

In my case, an element that had previously been rendered as

<Foo>
</Foo>



成为

became

<Foo></Foo>






当你在你的问题提到,这是实际上,由于一切都相当棘手的问题被密封/内部等,使得覆盖相当困难。我想我最大的问题就是试图获得一个的XmlWriter 接受 XmlWriterSettings :超越这种方法,我找不到任何办法让原来的 XmlTextWriterFull 尊重给出 XmlWriterSettings


As you alluded to in your question, this is actually quite a tricky problem due to everything being sealed/internal etc., making overrides rather difficult. I think my biggest problem was trying to get an XmlWriter to accept XmlWriterSettings: beyond this approach, I could find no way of getting the original XmlTextWriterFull to respect the given XmlWriterSettings.

MSDN 指出此方法:

XmlWriter.Create(XmlWriter, XmlWriterSettings)

可用于应用 XmlWriterSettings 的XmlWriter 。我不能得到这个工作,就像我想(压痕从来没有工作过,例如),并在反编译的代码,它不会出现,所有的设置都与这个特定的方法使用,因此为什么我的调用代码只是传递中在 OUTPUTFILE (一某种流将工作一样好)。

Can be used to apply the XmlWriterSettings to the XmlWriter. I couldn't get this to work like I wanted (the indentation never worked, for example), and upon decompiling the code, it does not appear that all the settings are used with this particular method, hence why my invocation code just passes in the outputFile (a stream of some sort would work just as well).

这篇关于如何使用覆盖无效对writeEndElement时使用XmlWriterSettings()()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆