3

I'm not able to remove the name of the Attribute Values in clsProduct from my xml. I tried using [XmlElement(ElementName = "Values", Type = typeof(clsValues)] for my List<clsValues> but it didn't give me the result I need.

You can see the result I need below.

Parts of my serialization class:

[Serializable]
public class clsProduct
{
    [XmlAttribute("ID")]
    public string ID { get; set; }

    [XmlAttribute("UserTypeID")]
    public string UserTypeID { get; set; }

    [XmlArrayItem(ElementName = "Values", Type = typeof(clsValues))]
    public List<clsValues> Values { get; set; }

}

[Serializable]
public class clsValues
{
    [XmlElement(ElementName = "Value")]
    public clsValue Value { get; set; }

    [XmlArray(ElementName = "MultiValue"),
    XmlArrayItem(ElementName = "Value")]
    public List<clsValue> MultiValue { get; set; }
}

[Serializable]
public class clsValue
{
    [XmlAttribute("AttributeID")]
    public string AttributeID { get; set; }

    [XmlText]
    public string Value { get; set; }
}

My current xml result:

<Product ID="PROD-01111010" UserTypeID="Product">
   <Values>
     <Values>
        <Value AttributeID="ATTR-7196">201607280755</Value>
     </Values>
     <Values>
        <Value AttributeID="ATTR-6236">PTFE 125 + 25% GF, Platte</Value>
     </Values>
     <Values>
        <MultiValue>
            <Value>PLATTE</Value>
            <Value>LUBRIFLON 225</Value>
            <Value>PLAQUE</Value>
            <Value>LUBRIFLON 22</Value>
        </MultiValue>
     </Values>
  </Values>
</Product>

Result I need:

<Product ID="PROD-01111010" UserTypeID="Product">
  <Values>
     <Value AttributeID="ATTR-7196">201607280755</Value>
     <Value AttributeID="ATTR-6236">PTFE 125 + 25% GF, Platte</Value>
     <MultiValue>
        <Value>PLATTE</Value>
        <Value>LUBRIFLON 225</Value>
        <Value>PLAQUE</Value>
        <Value>LUBRIFLON 22</Value>
     </MultiValue>
   </Values>
 </Product>

Can someone help?

Thanks

Edit: When I'm using

[XmlElement(ElementName = "Values", Type = typeof(clsValues))] public List<clsValues> Values { get; set; }

instead of XmlArrayItem I get this result:

<Product ID="PROD-01111010" UserTypeID="Product">
     <Values>
        <Value AttributeID="ATTR-7196">201607280755</Value>
     </Values>
     <Values>
        <Value AttributeID="ATTR-6236">PTFE 125 + 25% GF, Platte</Value>
     </Values>
     <Values>
        <MultiValue>
            <Value>PLATTE</Value>
            <Value>LUBRIFLON 225</Value>
            <Value>PLAQUE</Value>
            <Value>LUBRIFLON 22</Value>
        </MultiValue>
     </Values>
</Product>
3
  • 1
    As a side note, now would be a very good time to stop using the cls prefix and start following normal .NET naming conventions. Commented Jul 28, 2016 at 6:43
  • @JonSkeet I normally don't use prefixes. I didn't create the project I'm extending it and don't want to have two naming conventions in one application. Commented Jul 28, 2016 at 7:13
  • Well I'd suggest to your co-workers that they start following the naming conventions then - and don't forget that you're posting a Stack Overflow question; it doesn't have to be the exact code, so long as it shows the same exact problem. That means you can make it simpler and more conventional, to provide fewer distractions for readers. Commented Jul 28, 2016 at 7:15

4 Answers 4

2

Your issue relates to this property:

[XmlArrayItem(ElementName = "Values", Type = typeof(clsValues))]
public List<clsValues> Values { get; set; }

The implication is there are multiple elements called Values that have a specific type clsValues. And each of these have one or both of Value or MultiValue children.

What you want is the array to be an element Values and for the array items to be a choice between your two different element types - it either contains a Value element or a MultiValue element.

You can structure like this to achieve that:

public class Product
{
    [XmlAttribute("ID")]
    public string Id { get; set; }

    [XmlAttribute("UserTypeID")]
    public string UserTypeId { get; set; }

    [XmlArray("Values")]
    [XmlArrayItem("Value", typeof(Value))]
    [XmlArrayItem("MultiValue", typeof(MultiValue))]
    public List<object> Values { get; set; }
}

public class MultiValue
{
    [XmlElement(ElementName = "Value")]
    public List<Value> Values { get; set; }
}

public class Value
{
    [XmlAttribute("AttributeID")]
    public string AttributeId { get; set; }

    [XmlText]
    public string Text { get; set; }
}

See this fiddle for a working demo.

Sign up to request clarification or add additional context in comments.

Comments

1

May be you should use

[XmlElement(ElementName = "Values", Type = typeof(clsValues))]
public List<clsValues> Values { get; set; }

Instead of

[XmlArrayItem(ElementName = "Values", Type = typeof(clsValues))]

1 Comment

When I implement that the first and last <Values> disappears.
0

Try xml linq

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            XElement values = doc.Descendants("Values").FirstOrDefault();
            List<XElement> elements = values.Elements().ToList();
            for (int index = elements.Count() - 1; index >= 0; index--)
            {
                elements[index].ReplaceWith(elements[index].Elements());
            }
        }
    }
}

Comments

0

Reason, why it is serializating like that, is because XML is using second <Values></Values> as delimeter. It is needed because your clsValues object can has Value and MultiValue property set at the same time. In that case XML in your needed format

<Product ID="PROD-01111010" UserTypeID="Product">
  <Values>
     <Value AttributeID="ATTR-7196">201607280755</Value>
     <Value AttributeID="ATTR-6236">PTFE 125 + 25% GF, Platte</Value>
     <MultiValue>
        <Value>PLATTE</Value>
        <Value>LUBRIFLON 225</Value>
        <Value>PLAQUE</Value>
        <Value>LUBRIFLON 22</Value>
     </MultiValue>
   </Values>
 </Product>

could be backward interpreted as 1 object with Value set and 1 object with both Value and MultiValue set which is wrong, or as 1 object with Value set, 1 object with Value set and 1 object with MultiValue set which is correct. But XML parser can't know, which interpretation is correct. If you surrely know, that your object will always has only 1 property set, you can write your own Serializator and Deserializator with implemented one property rule.

1 Comment

So far as I understand your post, the serializer is not able to serialize an xml in my needed format?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.