3

在我们的应用程序中,无论对象的类型如何,我们都需要将对象的属性保存到同一个数据库表中,形式为propertyName、propertyValue、propertyType。我们决定使用 XamlWriter 来保存所有给定对象的属性。然后,我们使用 XamlReader 加载创建的 XAML,并将其转换回属性的值。这在大多数情况下都可以正常工作,除了空字符串。XamlWriter 将保存一个空字符串,如下所示。

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

XamlReader 看到此字符串并尝试创建一个字符串,但在要使用的 String 对象中找不到空构造函数,因此它会引发 ParserException。

我能想到的唯一解决方法是如果它是一个空字符串,则实际上不保存该属性。然后,当我加载属性时,我可以检查哪些属性不存在,这意味着它们将是空字符串。

是否有一些解决方法,或者是否有更好的方法来做到这一点?

4

2 回答 2

0

我也遇到了问题并在网上搜索了解决方案,但找不到解决方案。

我通过检查保存的 XML 并修复空字符串来解决它,如下所示(使用 XamlWriter 的输出提供 FixSavedXaml):

    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);
        }
    }
于 2015-04-09T08:04:20.373 回答
0

在尝试序列化字符串时,我们遇到了类似的问题。我们可以解决它的唯一方法是创建一个StringWrapper具有适当构造函数的结构或类。然后我们使用这种类型来加载和保存我们的字符串值。

于 2010-04-05T15:25:41.483 回答