1
votes

I'm trying to deserialize an XML with XmlSerializer (c#) that looks like:

    <strokes>
      <stroke timestamp="1405376883559">
        <coord x="58.425" y="43.2375" d="0.0"/>
        <coord x="58.6125" y="42.825" d="13.0"/>
        <coord x="58.7625" y="42.7125" d="26.0"/>
        <coord x="58.875" y="42.7125" d="40.0"/>
      </stroke>
      <stroke timestamp="1405376884991">
        <coord x="67.95" y="40.6125" d="0.0"/>
        <coord x="68.025" y="40.5" d="13.0"/>
        <coord x="68.0625" y="40.3875" d="26.0"/>
      </stroke>
      <stroke timestamp="1405376885557">
        <coord x="70.425" y="41.85" d="0.0"/>
        <coord x="70.35" y="42.0" d="13.0"/>
        <coord x="70.35" y="42.075" d="26.0"/>
        <coord x="70.4625" y="42.1125" d="40.0"/>
        <coord x="70.6125" y="42.15" d="53.0"/>
      </stroke>
      <stroke timestamp="1405376886058">
        <coord x="70.6875" y="44.175" d="0.0"/>
        <coord x="70.575" y="44.25" d="13.0"/>
      </stroke>
      <stroke timestamp="1405376886689">
        <coord x="78.375" y="42.7125" d="0.0"/>
        <coord x="78.1125" y="42.9" d="13.0"/>
        <coord x="77.8125" y="43.0875" d="26.0"/>
        <coord x="77.475" y="43.2375" d="40.0"/>
      </stroke>
      </stroke>
    </strokes>

and my faulty class looks like this

    [XmlRoot("strokes", IsNullable = false)]
    public class Strokes
    {
        private List<Stroke> strokes;
    }

    public class Stroke
    {
        public string timestamp;
        [XmlArrayAttribute("stroke")]
        List<coord> stroke;
    }
    [Serializable]
    public class coord
    {
        [XmlAttribute]
        public string x;
        [XmlAttribute]
        public string y;
        [XmlAttribute]
        public string d;
    }

I think I'm missing some class attributes for describing that the stroke object has an array and timestamp. I'm getting an "unknownNode" even triggered on the xml node "stroke"

How do I construct my c# object to fit this xml?

1
Shouldn't the parameter to your XmlArrayAttribute in the Stroke class be "coord"?Jim Mischel
All properties need to be public. Property needs to have {get; set;}. What you're doing is declaring a bunch of public fields. They need to be properties.Eric.K.Yung
@Eric.K.Yung: you are right about them needing to be public. They needn't be properties per se however, fields will be (de)serialized as well.TC.

1 Answers

1
votes

This should do the trick:

[XmlRoot("strokes", IsNullable = false)]
public class Strokes
{
    [XmlElement("stroke")]
    public List<Stroke> strokes;
}

public class Stroke
{
    [XmlAttribute]
    public string timestamp;

    [XmlElement("coord")]
    public List<coord> coords;
}

[Serializable]
public class coord
{
    [XmlAttribute]
    public string x;
    [XmlAttribute]
    public string y;
    [XmlAttribute]
    public string d;
}

They key is make everything that you want to (de)serialize public, and to use XmlElement instead of XmlArrayAttribute on the list of coords.

There's a really helpful tip in Mikael Svenson's answer to a similar question:

I did this by taking your xml, generating a schema (xsd) from it in Visual Studio. Then running xsd.exe on the schema to generate a class. (And some small edits)

If you do this for the XML you posted, you'd obtain the following working version of the list of coord elements for example:

[System.Xml.Serialization.XmlElementAttribute("coord")]
public strokesStrokeCoord[] coord {
    get {
        return this.coordField;
    }
    set {
        this.coordField = value;
    }
}