0

我们有一个 Windows Store 应用程序,它使用 XML 与我们的服务器进行通信以获取请求/响应,并使用 XmlSerializer 进行序列化。我们遇到的问题是我们的一种类型可以包含任意 XML 作为其属性之一。在非 WinRT 应用程序中,使用会一直如此。

public sealed ItemExtension {
    [XmlAttribute("source")]
    public string Source {get;set;}

    [XmlAnyElement]
    public XmlElement[] Data {get;set;}
}

这将允许我们在我们的数据库中拥有 XML

<extension source="foo"><randomXml><data/></randomXml></extension>

在 WinRT 中,不包含 XmlElement,System.Xml.XmlElement 不存在且 Windows.Data.Xml.Dom.XmlElement 不兼容。文档中提到了 XElement,但 XElement 不是受支持的 WinRT 类型,因此如果我尝试使用它,WinRT 项目将无法编译。

这是 Windows 应用商店应用程序的错误还是有足够的解决方法?

谢谢。

4

1 回答 1

0

到目前为止,我只找到了一个 hack 来让它工作。如果我们使用

[XmlAnyElement]
public object Data {get;set;}

这将正确地反序列化现有数据。在调试器中检查它时,它是 System.Xml.XmlElement 类型,它没有在 WinRT 中公开。所以没有办法直接设置它。由于我们发现 XmlSerializer 可以实例化和访问 System.Xml.XmlElement,因此我们使用它来处理设置它,方法是接收一个 object/xml 片段,将它包装在包含 [XmlAnyElement] 的包装器类型的容器 xml 中并调用 Deserialize on它让 XmlSerializer 实例化一个 XmlElement,然后可以在您希望序列化的目标对象上设置它。

对于获取数据,由于尝试读取此属性会在 UI 层中引发异常,并且尝试访问 InnerXml/OuterXml 也会引发异常,因此我们使用 XmlSerializer 将 XmlElement 序列化回字符串,然后可以随心所欲地使用它。

public sealed class XmlAnyElementContainer
{
    [XmlAnyElement]
    public object Data { get; set; }
}

public void SetData(object extensionObject)
{
    var objectSerializer = new XmlSerializer(extensionObject.GetType());

    var settings = new XmlWriterSettings()
    {
        Indent = false,
        OmitXmlDeclaration = true
    };

    var sb = new StringBuilder();
    using (var xmlWriter = XmlWriter.Create(sb, settings))
    {
        objectSerializer.Serialize(xmlWriter, extensionObject);
    }

    string objectXml = sb.ToString();

    string newXml = "<XmlAnyElementContainer>" + objectXml + "</XmlAnyElementContainer>";
    var xmlAnySerializer = new XmlSerializer(typeof(XmlAnyElementContainer));
    using (var sr = new StringReader(newXml))
    {
        [TargetPropertyToSerialize] = (xmlAnySerializer.Deserialize(sr) as XmlAnyElementContainer).Data;
    }
}
于 2014-01-22T18:38:22.357 回答