简体   繁体   中英

Deserializing xml with inner array

I'm trying to deserialize simple xml file:

<thesaurus xmlns="http://marklogic.com/xdmp/thesaurus">
    <metadata>
    </metadata>
    <entry>
        <term>a</term>
            <synonym>
                <term>as</term>
            </synonym>
    </entry>
    <entry>
        <term>b</term>
            <synonym>
                <term>bs</term>
            </synonym>
            <synonym>
                <term>bss</term>
            </synonym>
    </entry>
</thesaurus>

I'm using XmlSerializer like this:

var xmlSerializer = new XmlSerializer(typeof(Thesaurus));

var thesaurus = xmlSerializer.Deserialize(stream);

My model looks like this:

[Serializable]
[XmlRoot("thesaurus", Namespace = "http://marklogic.com/xdmp/thesaurus")]
public class Thesaurus
{
    [XmlElement("metadata")]
    public Metadata Metadata { get; set; }
    [XmlElement("entry")]
    public List<Entry> Entries { get; set; }
}

public class Metadata
{

}
public class Entry
{
    [XmlElement("term")]
    public string Term { get; set; }
    [XmlElement("synonym")]
    public String[] Synonym { get; set; }
}

So when I'm running this code, I get deserialized thesaurus object with parsed metadata and 1 entry with filled term and synonym fields. I can't get all of the entries here.

BUT

when I comment out Synonym field it starts giving me 2 entries in thesaurus object. I can't wrap entries in <entries> tag because it's some internal format of an application I'm feeding with this xml file.

Anyone has any ideas how to parse this xml file correctly? I tried searching for a solution, but this xml looks quite different than ones in examples.

Ok, so if you need to keep inside synonim field array of terms fields you need to change your Entry class to something like this:

public class Entry
{
     [XmlElement("term")]
     public string Term { get; set; }            

     [XmlElement("synonim")]
     public Term[] Synonym { get; set; }
}

also you'll need to add additional one:

public class Term
{
    [XmlElement("term")]
    public string Value { get; set; }
}

This way you'll have what you need. So, additional hierarchy level was added by additional class.

Please find below code for your test:

        var xmlSerializer = new XmlSerializer(typeof(Thesaurus));

        var r = new Thesaurus();
        r.Entries = new List<Entry>();
        r.Metadata = new Metadata();

        r.Entries.Add(new Entry()
        {
            Synonym = new Term[] { new Term(){Value = "1"}, new Term() {Value = "2"},   },
            Term = "Term1"
        });

        r.Entries.Add(new Entry()
        {
            Synonym = new Term[] { new Term() { Value = "3" }, new Term() { Value = "4" }, },
            Term = "Term2"
        });

        using (TextWriter writer = new StreamWriter(@"c:\111.xml"))
        {
            xmlSerializer.Serialize(writer, r);
            writer.Close();
        }


        using (TextReader reader = new StreamReader(@"c:\111.xml"))
        {
            Thesaurus tt = xmlSerializer.Deserialize(reader) as Thesaurus;
            Console.Write(tt.Entries.Count);
            reader.Close();
        }

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