You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用XmlSerializer序列化含anyType元素的string数组时丢失xsi:type属性的原因咨询

Why the xsi:type Attribute is Missing

The issue boils down to how XmlSerializer handles type information by default: it only includes the xsi:type attribute when the actual runtime type of an element doesn't match the declared base type for that element.

In your case, you're using a string[] to map to the <anyType> elements. Since string is the exact type XmlSerializer expects for the array items (and it's compatible with the generic anyType), it sees no need to explicitly add the xsi:type="xsd:string" attribute—it assumes the receiver will know the type from the schema or the property declaration.

Fixes to Get the Desired XML Output

Here are a few straightforward solutions to force the xsi:type attribute to appear:

1. Switch to object[] (Simplest Approach)

Change your property to use object[] instead of string[]. When you store string values in an object array, XmlSerializer recognizes that the runtime type (string) is different from the declared type (object), so it will automatically add the xsi:type attribute:

[XmlArrayItem("anyType", IsNullable = true)]
public object[] FieldValues { get; set; }

When populating the array, just cast your strings to objects:

FieldValues = new[] { "val1", "val2", "val3" }.Cast<object>().ToArray();

This will produce the XML you expect, with each <anyType> element carrying the xsi:type="xsd:string" attribute.

2. Use XmlAttributeOverrides to Force Type Output

If you need to keep using string[], you can override the serializer's behavior to treat each array item as an object (instead of string), which triggers the xsi:type attribute:

var overrides = new XmlAttributeOverrides();
var arrayItemAttr = new XmlArrayItemAttribute("anyType", typeof(string))
{
    IsNullable = true,
    Type = typeof(object) // Tell serializer to treat items as object
};
overrides.Add(typeof(YourTargetClass), "FieldValues", arrayItemAttr);

// Use this custom serializer instead of the default one
var serializer = new XmlSerializer(typeof(YourTargetClass), overrides);

3. Implement IXmlSerializable (Full Control)

For complete control over the XML structure, implement the IXmlSerializable interface to manually write the xsi:type attribute:

public class YourTargetClass : IXmlSerializable
{
    public string[] FieldValues { get; set; }

    public XmlSchema GetSchema() => null;

    public void ReadXml(XmlReader reader)
    {
        // Handle deserialization (parse the <anyType> elements)
        reader.ReadStartElement("FieldValues");
        var values = new List<string>();
        while (reader.NodeType != XmlNodeType.EndElement)
        {
            if (reader.Name == "anyType")
            {
                values.Add(reader.ReadElementContentAsString());
            }
            else
            {
                reader.Skip();
            }
        }
        reader.ReadEndElement();
        FieldValues = values.ToArray();
    }

    public void WriteXml(XmlWriter writer)
    {
        writer.WriteStartElement("FieldValues");
        if (FieldValues != null)
        {
            foreach (var val in FieldValues)
            {
                writer.WriteStartElement("anyType");
                // Explicitly write the xsi:type attribute
                writer.WriteAttributeString(
                    "xsi", "type", 
                    "http://www.w3.org/2001/XMLSchema-instance", 
                    "xsd:string");
                if (val != null)
                {
                    writer.WriteString(val);
                }
                writer.WriteEndElement();
            }
        }
        writer.WriteEndElement();
    }
}

This approach lets you dictate exactly how the XML is structured, ensuring the xsi:type attribute is included every time.


内容的提问来源于stack exchange,提问作者Amichai Simcha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 12:47:46