XamlReader.Parse 在空字符串上引发异常

发布于 2024-08-25 22:09:36 字数 530 浏览 6 评论 0原文

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

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

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

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

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

In our app, we need to save properties of objects to the same database table regardless of the type of object, in the form of propertyName, propertyValue, propertyType. We decided to use XamlWriter to save all of the given object's properties. We then use XamlReader to load up the XAML that was created, and turn it back into the value for the property. This works fine for the most part, except for empty strings. The XamlWriter will save an empty string as below.

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

The XamlReader sees this string and tries to create a string, but can't find an empty constructor in the String object to use, so it throws a ParserException.

The only workaround that I can think of is to not actually save the property if it is an empty string. Then, as I load up the properties, I can check for which ones did not exist, which means they would have been empty strings.

Is there some workaround for this, or is there even a better way of doing this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

靖瑶 2024-09-01 22:09:36

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

We had a similar problem to this when trying to serialize strings. The only way we could resolve it was to create a StringWrapper struct or class that had the appropriate constructors. We then used this type to load and save our string values.

爱冒险 2024-09-01 22:09:36

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

我通过检查保存的 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);
        }
    }

I also got the problem and searched the web for a solution but could not find one.

I solved it by inspecting the saved XML and fixing the empty strings, like this (feed FixSavedXaml with the output from 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);
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文