【问题标题】:Serialising an XML element and XML array item of the same name序列化同名的 XML 元素和 XML 数组项
【发布时间】:2018-10-29 23:50:03
【问题描述】:

我想序列化来自第三方服务的 XML 文档,这些文档可以是两种格式中的任何一种(为了便于阅读,我添加了缩进):

1.

<STADMessage>Invalid Request, no content provided!</STADMessage>

2.

<STADMessage>
    <Message>Invalid Request, see log for detail using reference: ASDFL210359872305982035</Message>
</STADMessage>

现在我正在破解 XML 文档,然后用以下代码对其进行序列化

xmlDocument.Replace("<STADMessage><Message>", "<STADMessages><Message>")
           .Replace("</Message></STADMessage>", "</Message></STADMessages>");

序列化类的片段

[XmlElement(ElementName = "STADMessage", IsNullable = true)]
public string STADMessage { get; set; }

[XmlArray(ElementName = "STADMessages", IsNullable = true)]
[XmlArrayItem("Message", typeof(string))]
public List<string> STADMessages { get; set; }

有没有更清洁的方法?

【问题讨论】:

  • 呃,他们这样做太丑了。您应该向他们的开发团队提交一张票,并教他们standardization 是什么。

标签: c# .net serialization xml-serialization


【解决方案1】:

如果您可以让他们按照@FrankerZ 的建议将其更改为适当的结构,那将是理想的。如果你不能,我希望这会有所帮助。

您可以使用自定义序列化对象来解释变化,该对象根据传入的节点类型反序列化

将您的 STADMessage 属性的类型更改为自定义类型(我称它为 STADMessage):

[XmlElement(ElementName = "STADMessage", IsNullable = true)]
public STADMessage STADMessage { get; set; }

这是STADMessage 类:

public class MySTADMessage : IXmlSerializable
{
    public string Message { get; set; }

    public XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(XmlReader reader)
    {
        // IsNullable = true is ignored, apparently.  You won't get an actual
        // null for properties deserialized this way because the serializer
        // already created an instance of this class.
        if (reader.GetAttribute("nil", XmlSchema.InstanceNamespace) == "true")
            return;

        reader.ReadStartElement();

        while (reader.NodeType == XmlNodeType.Whitespace)
            reader.Read();

        if (reader.NodeType == XmlNodeType.Text)
        {
            Message = reader.ReadContentAsString();
        }
        else if (reader.NodeType == XmlNodeType.Element)
        {
            if (reader.Name != "Message")
                throw new Exception("Unexpected element name.");

            reader.ReadStartElement();
            if (reader.NodeType == XmlNodeType.Text)
            {
                Message = reader.ReadContentAsString();
            }
            else
            {
                throw new Exception("Unexpected node type.");
            }
            reader.ReadEndElement();
        }
        else
        {
            throw new Exception("Unexpected node type.");
        }
        reader.ReadEndElement();
    }

    public void WriteXml(XmlWriter writer)
    {
        // Not having the extra Message element is simpler.
        writer.WriteString(Message);
    }
}

它很粗糙,相当按照今天的标准正确地实现了IXmlSerializable,而且它可能不能说明一切,但它应该能让你开始。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-14
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    相关资源
    最近更新 更多