19

The XML I am getting is provided by an outside source so I don't have the ability to easily reformat it. I would like to use xml attributes on my entities instead of having to write a linq query that knows how the XML and entity is formatted. Here is an example:

<?xml version="1.0"?>
<TERMS>
    <TERM>
        <ID>2013-2</ID>
        <DESC>Spring 2013</DESC>
    </TERM>
    <TERM>
        <ID>2013-3</ID>
        <DESC>Summer 2013 Jun&amp;Jul</DESC>
    </TERM>
</TERMS>

I know the the XMLSerializer expects ArrayOfTerm instead of TERMS for example, but that I can tweak my entity to use a different element name with the xml attributes such as this:

public class TermData
{
    [XmlArray("TERMS")]
    [XmlArrayItem("TERM")]
    public List<Term> terms;
}

public class Term
{
    [XmlElement("ID")]
    public string id;

    [XmlElement("DESC")]
    public string desc;
}

and I am deserializing the data like so:

TermData data;

XmlSerializer serializer = new XmlSerializer(typeof(TermData));
using (StringReader reader = new StringReader(xml))
{
   data = (TermData)serializer.Deserialize(reader);
}

return View(data.terms);

The problem I am facing is that TERMS is the root and the array itself. If the XML were to have a root element that was not the array, I could edit my TermData class like so and it would deserialize correctly (already tested).

[XmlRoot("ROOT")]
public class TermData
{
    [XmlArray("TERMS")]
    [XmlArrayItem("TERM")]
    public List<Term> terms;
}

Note that using TERMS as the XMLRoot does not work. Right now, my code is throwing

 InvalidOperationException: There is an error in XML document (2,2).
 InnerException: "<TERMS xmlns=" was not expected.

This would lead me to believe that the XML is not formatted correctly, but from my understanding the example I gave is perfectly valid XML.

This would all be trivial if I could edit the source xml, but there could be tons of other responses like this and I need to be able to flex for whatever I might get. What I'm trying to confirm is whether or not the XMLSerializer can support this type of XML structure. I've tested just about everything and can't get it deserialize without editing the XML. It would also be convenient if I didn't have to define a wrapper class (TermData) to hold the list, but this seems to only work if the xml follows the naming conventions for the serializer (ArrayOfTerm, etc).

2
  • 1
    How large is your file? I ran into a similar issue (trying to read log4net XML files) and what I did was load in the XML, arbitrarily inject the appropriate root tags, and moved from there. Commented Mar 6, 2013 at 21:58
  • Injecting a root element could be a solution. I hadn't actually thought of that so thanks for the suggestion. Though this problem seems like it should be a solved one without that sort of work around. Commented Mar 6, 2013 at 22:15

1 Answer 1

24

Maybe you can try :

[XmlRoot("TERMS")]
public class TermData
{
    public TermData()
     {
       terms = new List<Term>();
     }

    [XmlElement("TERM")]
    public List<Term> terms{get;set;}
}

public class Term
{
    [XmlElement("ID")]
    public string id{get;set;}

    [XmlElement("DESC")]
    public string desc{get;set;}
}

Hope this will help,

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

7 Comments

Tried this and it does not deserialize. TermData.terms has a Count of 0.
@pixelshaded : added a public constructor for the class which initializes the list. This should help
still getting an empty list
@pixelshaded overlooked that all fields should be properties. Updated that too
note that the constructor for TermData and accessors were not required
|

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.