简体   繁体   中英

XmlAttributeOverrides attaching an attribute to an element

I have the following code which is throwing an error...

The error...

For non-array types, you may use the following attributes: XmlAttribute, XmlText, XmlElement, or XmlAnyElement.

The code (last line in Go method is throwing the exception)...

    public void Go(Type typeToSerialize, object itemToSerialize)
    {
        Dictionary<string, bool> processedList = new Dictionary<string, bool>();
        XmlAttributeOverrides overrides = new XmlAttributeOverrides();

        AttachXmlTransforms(overrides, itemToSerialize.GetType(), processedList);

        s = new XmlSerializer(typeToSerialize, overrides);
    }

    private static void AttachXmlTransforms(XmlAttributeOverrides overrides, Type root,
        Dictionary<string, bool> processedList)
    {
        foreach (PropertyInfo pi in root.GetProperties())
        {
            string keyName = pi.DeclaringType + "-" + pi.Name;

            if ((pi.PropertyType == typeof(DateTime) || pi.PropertyType == typeof(DateTime?))
                && !processedList.ContainsKey(keyName))
            {
                XmlAttributes attributes = new XmlAttributes();

                attributes.XmlElements.Add(new XmlElementAttribute(pi.Name));
                //attributes.XmlAnyAttribute = new XmlAnyAttributeAttribute();
                attributes.XmlAttribute = new XmlAttributeAttribute("dval");

                //attributes.XmlIgnore = true;

                processedList.Add(keyName, true);


                overrides.Add(pi.DeclaringType, pi.Name, attributes);
            }

            if (pi.MemberType == MemberTypes.Property && !pi.PropertyType.IsPrimitive
                && pi.PropertyType.IsPublic && pi.PropertyType.IsClass
                && pi.PropertyType != typeof(DateTime))
            {
                AttachXmlTransforms(overrides, pi.PropertyType, processedList);
            }
        }
    }

I'm attempting to add an attribute (dval) to only DateTime elements (this is an external requirement)...

From this...

   <CreatedDate>01/01/2012</CreatedDate>

To this...

   <CreatedDate dval="01/01/2012">01/01/2012</CreatedDate>

Is there a way to add an attribute to a normal non-array type element?

I presume that you're having trouble with the line

attributes.XmlElements.Add(new XmlElementAttribute(pi.Name))

First off, judging by the naming convention, I'm guessing that XmlElements is not an Xml Element, but it's a collection of elements.

Also, judging by your error message, the XmlElements Add method doesn't take your XmlElementAttribute as a parameter, instead it takes a XmlAttribute, XmlText, XmlElement, or XmlAnyElement.

I ended up approching this a different way...

1) Convert the object to XML

2) Run the following...

        using (MemoryStream memStm = new MemoryStream())
        {
            // Serialize the object using the standard DC serializer.
            s.WriteObject(memStm, graph);

            // Fix the memstream location.
            memStm.Seek(0, SeekOrigin.Begin);

            // Load the serialized document.
            XDocument document = XDocument.Load(memStm);

            foreach (KeyValuePair<string, ItemToAmend> kvp in _processedDateTimes)
            {
                // Locate the datetime objects.
                IEnumerable<XElement> t = from el in document.Descendants(XName.Get(kvp.Value.ProperyName, kvp.Value.PropertyNamespace))
                                          select el;

                // Add the attribute to each element.
                foreach (XElement e in t)
                {
                    string convertedDate = string.Empty;

                    if (!string.IsNullOrEmpty(e.Value))
                    {
                        DateTime converted = DateTime.Parse(e.Value);

                        convertedDate = string.Format(new MyBtecDateTimeFormatter(), "{0}", converted);
                    }

                    e.Add(new XAttribute(XName.Get("dval"), convertedDate));
                }
            }

            // Write the document to the steam.
            document.Save(writer);
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM