2

I have a strange problem with my customer - I am reading an XML document (actually an InfoPath document) with XmlSerializer, modifying it, then writing out an XML document using the XmlSerializer, and then add some processing instructions by using the XmlTextWriter. All works well, and the resulting document is actually fully XML conform and can be read by InfoPath. One change that happens in the structure is however that the original document has all empty tags written in the form <A></A>, and when my document is written, it becomes <A/>. Actually exactly the same due to XML standards. But, my customer (a big company) apparently has some check/validation scripts with hardcoded <A></A>, and they fail. He's is now upset, and is too lazy to change his scripts, and wants the <A></A> notation! How can I setup XmlTextWriter to do it?

Ondrej Tucny
  • 27,626
  • 6
  • 70
  • 90
Petr Osipov
  • 621
  • 6
  • 16

2 Answers2

5

You can do this by providing XmlSerializer with your own XmlWriter descendant, which would override the WriteEndElement method. By default, this method produces an empty element (<a />) or a closing element (</a>) depending on the contents of the element being output. You can change the behavior to always produce a full closing element.

public class MyXmlWriter : XmlTextWriter
{
    // …constructors etc. omitted for the sake of simplicity…

    public override void WriteEndElement()
    {
        // this should do the trick
        WriteFullEndElement();
    }
}

However, there's some more work needed, e.g. the Async version of this method, but in principle, it should be easy to achieve like above. I'd recommend looking into the source code of XmlTextWriter.WriteEndElement and deriving a version that better fits your case.

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
Ondrej Tucny
  • 27,626
  • 6
  • 70
  • 90
  • XmlTextWriter doesn't override WriteEndElementAsync, (and XmlWriter's implementation just throws an exception), so I *think* this code might be sufficient on its own? – canton7 Mar 05 '19 at 09:47
  • Just taken over the solution - works as desired! One question however - now it drops in a new line break. Any way to control it? – Petr Osipov Mar 05 '19 at 09:50
  • @PetrOsipov Look at [`XmlWriterSettings`](https://learn.microsoft.com/en-us/dotnet/api/system.xml.xmlwritersettings) which provide a bunch of settings that might be helpful in further formatting the output. – Ondrej Tucny Mar 05 '19 at 09:56
  • Actually, there are no settings which can control that. At least, none are bringing the desired effect. I am now trying to override the WriteFullEndElement. While it is overridable, I cant just take the official class library and fix what I want - myriad of internal, private or protected fields, etc is used, which makes it not easy to fix the functionality.... – Petr Osipov Mar 06 '19 at 09:56
0

Honestly I think if you're going to use the built in Serializer then you'd be better off doing a find/replace. It doesn't look like you can override the actual form of the tags, at least I've not seen a way to do it even overriding some of the methods.

As a result I would put a check in that says if a tag is empty, put in a value such as "[[[EMPTYVALUE]]]" so you end up with

<A>[[[EMPTYVALUE]]]</A>

Then generated your XML, and before saving the XML file, convert it to a string, and replace "<A>[[[EMPTYVALUE]]]</A>" with "<A></A>"

You could just do a replace on <A/> but I think it's safer to create a bigger string to replace.

NibblyPig
  • 51,118
  • 72
  • 200
  • 356