序列化同名的 XML 元素和 XML 数组项
Serialising an XML element and XML array item of the same name
我想序列化来自第三方服务的 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>");
序列化的片段class
[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; }
有没有更简洁的方法?
如果您可以让他们将其更改为@FrankerZ 推荐的适当结构,那将是理想的。如果你不能,我希望这对你有所帮助。
您可以使用自定义序列化对象来解释变化,该对象根据传入节点类型反序列化。
将您的 STADMessage 属性 的类型更改为自定义类型(我称它为 STADMessage
):
[XmlElement(ElementName = "STADMessage", IsNullable = true)]
public STADMessage STADMessage { get; set; }
这里是 STADMessage
class:
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
正确实施,而且它可能无法解释所有问题,但它应该可以帮助您入门.
我想序列化来自第三方服务的 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>");
序列化的片段class
[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; }
有没有更简洁的方法?
如果您可以让他们将其更改为@FrankerZ 推荐的适当结构,那将是理想的。如果你不能,我希望这对你有所帮助。
您可以使用自定义序列化对象来解释变化,该对象根据传入节点类型反序列化。
将您的 STADMessage 属性 的类型更改为自定义类型(我称它为 STADMessage
):
[XmlElement(ElementName = "STADMessage", IsNullable = true)]
public STADMessage STADMessage { get; set; }
这里是 STADMessage
class:
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
正确实施,而且它可能无法解释所有问题,但它应该可以帮助您入门.