Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
411 views
in Technique[技术] by (71.8m points)

c# - Ignore outer elements using XmlSerializer

I am trying to deserialize the XML document:

<?xml version='1.0' encoding='UTF-8'?>
<eveapi version="2">
  <currentTime>2013-07-07 07:24:20</currentTime>
  <result>
    <rowset name="characters" key="characterID" columns="name,characterID,corporationName,corporationID">
      <row name="xxxxx" characterID="1234" corporationName="xxxx" corporationID="1234" />
    </rowset>
  </result>
  <cachedUntil>2013-07-07 07:40:39</cachedUntil>
</eveapi>

My model is:

[XmlRoot("rowset")]
public class CharacterList
{
    public CharacterList() { Characters = new List<Character>(); }

    [XmlElement("row")]
    public List<Character> Characters { get; set; }
}

public class Character
{
    [XmlElement("name")]
    private string name { get; set; }

    [XmlElement("characterID")]
    private int Id { get; set; }

    [XmlElement("corporationName")]
    private string corporationName { get; set; }

    [XmlElement("corporationID")]
    private int corporationId { get; set; }
}

My deserialization code is:

XmlRootAttribute xRoot = new XmlRootAttribute();
xRoot.ElementName = "result";
xRoot.IsNullable = true;
var serializer = new XmlSerializer(typeof(Character), xRoot);
var list = (CharacterList) serializer.Deserialize(output);

However, I am getting an exception:

System.InvalidOperationException: There is an error in XML document (2,2).

with an inner type:

System.InvalidOperationException: <eveapi xmlns=''> was not expected.

I'm pretty sure this is because of the outer information I do not need. Is there a way I can ignore it? my other thought was I could write wrapper classes for the rest of the schema, then just ignore what I don't care about. However, I was hoping there is an easier way. I've been stuck on this for a while, any help would be appreciated.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can use an XmlReader to navigate to the inner element and use the XmlSerializer from there:

   using (XmlReader reader = XmlReader.Create("c:\your.xml"))
    {
        reader.MoveToContent();
        reader.ReadToDescendant("rowset");
        var serializer = new XmlSerializer(typeof(CharacterList));
        var list = (CharacterList)serializer.Deserialize(reader);
    }

Please also note that there are also some issues in your model:

  • Properties should be public.
  • Use XmlAttribute for attributes instead of XmlElement
  • Use typeof(CharacterList) instead of typeof(Character)

    [XmlRoot("rowset")]
    public class CharacterList
    {
        public CharacterList() { Characters = new List<Character>(); }
    
        [XmlElement("row")]
        public List<Character> Characters { get; set; }
    }
    
    public class Character
    {
        [XmlAttribute("name")]
        public  string name { get; set; }
    
        [XmlAttribute("characterID")]
        public int Id { get; set; }
    
        [XmlAttribute("corporationName")]
        public string corporationName { get; set; }
    
        [XmlAttribute("corporationID")]
        public int corporationId { get; set; }
    }
    

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...