Как обрабатывать XmlWriter.Create в подклассе

Мне нужно изменить поведение XmlWriter для моего проекта, чтобы изменить способ сериализации пустых элементов xml. В настоящее время мой код использует XmlWriter и XmlSerializer следующим образом:

public string Serialize(object o)
{
    XmlWriterSettings settings = new XmlWriterSettings();
    ...

    StringWriter stringWriter = new StringWriter();

    XmlWriter xmlWriter = XmlWriter.Create(stringWriter, settings);
    XmlSerializer serializer = new XmlSerializer(o.GetType());
    serializer.Serialize(xmlWriter, o);

    return stringWriter.ToString();
}

При сериализации моего xml пустые элементы сериализуются в <emptyElement/>, но мне нужен xml для сериализации пустых элементов в <emptyElement></emptyElement>. Лучшее решение, которое я нашел для этого, было указано на этом форуме Microsoft несколько лет назад: https://social.msdn.microsoft.com/Forums/en-US/979315cf-6727-4979-a554-316218ab8b24/xml-serialize-empty-elements?forum=xmlandnetfx

Более быстрый и безопасный способ сделать это — написать собственный подкласс XmlWriter и передать его XmlSerializer.

YourXmlWriter объединит стандартный и преобразует все вызовы WriteEndElement() в вызовы WriteFullEndElement().

Я попытался написать свой собственный подкласс XmlWriter, переопределив два метода, которые мне нужно переопределить:

public abstract class CustomXmlWriter : XmlWriter
    {
        public override void WriteEndElement()
        {
            WriteFullEndElement();
        }

        public override Task WriteEndElementAsync()
        {
            return WriteFullEndElementAsync();
        }
    }

Теоретически я считаю, что это должно работать. Однако при попытке использовать код я натыкаюсь на кирпичную стену вокруг XmlWriter.Create. Я не могу привести полученный XmlWriter к моему CustomXmlWriter по очевидным причинам, и я не могу переопределить метод, так как это статический метод.

Как мне поступать со статическим методом Create? Единственный другой способ, который я могу придумать, — это отказаться от идеи моего собственного CustomXmlWriter и просто манипулировать строкой в ​​конце моего метода, но это кажется очень неправильным. Я не знаю, возможно ли то, чего я пытаюсь достичь, или есть ли где-то простая настройка, которую я нигде не могу найти.


person Steve Norwood    schedule 25.06.2019    source источник
comment
Спецификация XML позволяет нулевым элементам иметь только один тег. Я бы рекомендовал исправить программное обеспечение, которое требует двух тегов для нулевого элемента.   -  person jdweng    schedule 25.06.2019
comment
@jdweng Я полностью согласен. В настоящее время мы работаем над тем, чтобы увидеть, возможно ли это, но в краткосрочной перспективе мы пытаемся найти исправление, в первую очередь принудительно добавив два тега в XML.   -  person Steve Norwood    schedule 25.06.2019
comment
В краткосрочной перспективе мне может быть проще использовать регулярное выражение, хотя я никогда не рекомендую использовать регулярное выражение в xml или html.   -  person jdweng    schedule 25.06.2019


Ответы (1)


Попробуйте использовать Regex в качестве временного исправления. Входной переменной может быть вся строка xml, и она заменит каждое вхождение. :

        static void Main(string[] args)
        {

            string input = "<emptyElement/>";
            string patternNullTag = @"\<(?'tagname'\w+)/\>";
            string output = Regex.Replace(input, patternNullTag, ReplaceNullElement);
        }
        static string ReplaceNullElement(Match match)
        {
            string tagname = match.Value.Replace("<", "").Replace("/>", "");
            string newElement = "<" + tagname + ">" + "</" + tagname + ">";
            return newElement;
        }
person jdweng    schedule 25.06.2019