XamlReader.Parse создает исключение для пустой строки - PullRequest
3 голосов
/ 23 марта 2010

В нашем приложении нам необходимо сохранить свойства объектов в одной и той же таблице базы данных независимо от типа объекта в форме propertyName, propertyValue, propertyType. Мы решили использовать XamlWriter для сохранения всех свойств данного объекта. Затем мы используем XamlReader для загрузки созданного XAML и возвращаем его обратно в значение для свойства. Это прекрасно работает по большей части, за исключением пустых строк. XamlWriter сохранит пустую строку, как показано ниже.

<String xmlns="clr-namespace:System;assembly=mscorlib" xml:space="preserve" /> 

XamlReader видит эту строку и пытается создать строку, но не может найти пустой конструктор в объекте String для использования, поэтому он генерирует ParserException.

Единственный обходной путь, о котором я могу подумать, - это на самом деле не сохранять свойство, если оно является пустой строкой. Затем, загружая свойства, я могу проверить, какие из них не существуют, что означает, что они были бы пустыми строками.

Есть ли какое-то решение для этого или есть даже лучший способ сделать это?

Ответы [ 2 ]

0 голосов
/ 09 апреля 2015

Я также получил проблему и искал решение в сети, но не смог найти ее.

Я решил это, проверив сохраненный XML-файл и исправив пустые строки, например так (канал FixSavedXaml с выводом из XamlWriter):

    static string FixSavedXaml(string xaml)
    {
        bool isFixed = false;
        var xmlDocument = new System.Xml.XmlDocument();
        xmlDocument.LoadXml(xaml);
        FixSavedXmlElement(xmlDocument.DocumentElement, ref isFixed);
        if (isFixed) // Only bothering with generating new xml if something was fixed
        {
            StringBuilder xmlStringBuilder = new StringBuilder();
            var settings = new System.Xml.XmlWriterSettings();
            settings.Indent = false;
            settings.OmitXmlDeclaration = true;

            using (var xmlWriter = System.Xml.XmlWriter.Create(xmlStringBuilder, settings))
            {
                xmlDocument.Save(xmlWriter);
            }

            return xmlStringBuilder.ToString();
        }

        return xaml;
    }

    static void FixSavedXmlElement(System.Xml.XmlElement xmlElement, ref bool isFixed)
    {
        // Empty strings are written as self-closed element by XamlWriter,
        // and the XamlReader can not handle this because it can not find an empty constructor and throws an exception.
        // To fix this we change it to use start and end tag instead (by setting IsEmpty to false on the XmlElement).
        if (xmlElement.LocalName == "String" &&
            xmlElement.NamespaceURI == "clr-namespace:System;assembly=mscorlib")
        {
            xmlElement.IsEmpty = false;
            isFixed = true;
        }

        foreach (var childElement in xmlElement.ChildNodes.OfType<System.Xml.XmlElement>())
        {
            FixSavedXmlElement(childElement, ref isFixed);
        }
    }
0 голосов
/ 05 апреля 2010

У нас была похожая проблема при попытке сериализации строк. Единственный способ разрешить это - создать структуру или класс StringWrapper, которые имели бы соответствующие конструкторы. Затем мы использовали этот тип для загрузки и сохранения наших строковых значений.

...