views:

390

answers:

3

I am trying to create serializable class but I want to map second level element to my property of class. What's the best way of doing this.

Example xml & class

<SearchResult>
 <Head>
  <Title q="test">My search Result</Title>
 </Head>
 <Results>
  <Result>...</Result>
  <Result>...</Result>
  <Result>...</Result>
 </Results>
</SearchResult>

[Serializable]
[XmlRoot(ElementName = "GSP")]
public class SearchResult
{
    **[XmlElement(ElementName=@"Head\Title")]**
    public string Title { get; set; }

    [XmlArray(ElementName = "Results")]
    [XmlArrayItem(ElementName = "Result")]
    public List<ResultItem> mySearchResultItems { get; set; }


}

[Serializable]
public class ResultItem
{
...
}

So, In my example I would like to map Title property to <Head><Title> text value in xml

Thanks for your help!!

+2  A: 

You can't do that. You need to create another class for the <Head> element

[XmlRoot(ElementName = "GSP")]
public class SearchResult
{
    [XmlElement(ElementName = "Head")]
    public Head Head { get; set; }

    [XmlArray(ElementName = "Results")]
    [XmlArrayItem(ElementName = "Result")]
    public List<ResultItem> mySearchResultItems { get; set; }


}

public class Head
{
    [XmlElement(ElementName = "Title")]
    public string Title { get; set; }
}

public class ResultItem
{
...
}

Also, if the Title element must have an attribute, you will also need to create a new class for the Title element...

By the way, the [Serializable] attribute has nothing to do with XML serialization...

Thomas Levesque
Hi Thomas, I was afraid you would say that. How would I do custom serialization code instead of creating deeper level of classes (which I frankly don't need)?
Jay
You can implement the IXmlSerializable interface, it will give you full control over the serialization. But it can be a tedious task...
Thomas Levesque
A: 

You don't need custom serialization. Thomas Levesque is correct, but you can get what you want using the same design approach you employed for the Results.

Example:

    [XmlRoot(ElementName = "GSP")]
    public class SearchResult
    {
        //public string Title { get; set; }
        [XmlArray(ElementName = "Header")]
        [XmlArrayItem(ElementName = "Title")]
        public List<String> myHeaderItems { get; set; }

        [XmlArray(ElementName = "Results")]
        [XmlArrayItem(ElementName = "Result")]
        public List<ResultItem> mySearchResultItems { get; set; }

        public SearchResult()
        {
            myHeaderItems = new List<String>();
            mySearchResultItems= new List<ResultItem>();
        }

        public SearchResult(string title) : this()
        {
            myHeaderItems.Add(title);
        }
    }

    public class ResultItem
    {
        [XmlText]
        public String Flavor;
    }


    public void Run()
    {
        SearchResult sr = new SearchResult("Search1");
        sr.mySearchResultItems.Add(new ResultItem() {Flavor = "one" }) ; 
        sr.mySearchResultItems.Add(new ResultItem() {Flavor = "two" }) ; 

        var s1 = new XmlSerializer(typeof(SearchResult));

        Console.WriteLine("Serialized:\n{0}", s1.SerializeToString(sr));
    }

Produces this output:

<GSP>
  <Header>
    <Title>Search1</Title>
  </Header>
  <Results>
    <Result>one</Result>
    <Result>two</Result>
  </Results>
</GSP>
Cheeso
A: 

on the same kinda theme anyone know how to make:

<test>
  <lists>
    <list category="a">
      <item name="abc" />
      <item name="bca" />
      <item name="cab" />
    </list>
    <list category="b">
      <item name="cba" />
      <item name="bac" />
    </list>
  </lists>
</test>

the xml comes from an API that I have to use so really I'm deserializing this, but need to know how to make the classes in C# to hold this.

matt_lethargic