0

I have this XML structure:

<?xml version="1.0" encoding="UTF-8" ?>
<response uri="/api/" action="EXPORT">
<result>
    <rows>
        <row>
            <column name="Name1">Value1</column>
            <column name="Name2">Value2</column>
        </row>
        <row>
            <column name="Name1">Value1</column>
            <column name="Name2">Value2</column>
        </row>
    </rows>
</result>
</response>

I'm trying to deserialize the XML into a list object like so:

 List<ModelXML> model;

        using (TextReader reader = new StringReader(xml_str))
        {
            System.Xml.Serialization.XmlSerializer deserializer = new System.Xml.Serialization.XmlSerializer(typeof(List<ModelXML>),
                new XmlRootAttribute("rows"));
            model= (List<ModelXML>)deserializer.Deserialize(reader);
        }

My parameters in the ModelXML Class:

    [XmlElement("Name1")]
    public string Name1{ set; get; }
    [XmlElement("Name2")]
    public string Name2{ set; get; }

And finally I'm getting this error:

The '=' character, hexadecimal value 0x3D, cannot be included in a name. Line 1, position 13.

What I'm doing wrong? thanks.

1
  • Code seems to be correct, did you try to check if there are hidden characters in the input string? Is your input string comes from a file? Commented Jun 24, 2017 at 5:49

2 Answers 2

1

Here how you can solve your issue

First you have to change your model

[XmlRoot(ElementName = "column")]
    public class Column
    {
        [XmlAttribute(AttributeName = "name")]
        public string Name { get; set; }
        [XmlText]
        public string Text { get; set; }
    }

    [XmlRoot(ElementName = "row")]
    public class Row
    {
        [XmlElement(ElementName = "column")]
        public List<Column> Column { get; set; }
    }

    [XmlRoot(ElementName = "rows")]
    public class Rows
    {
        [XmlElement(ElementName = "row")]
        public List<Row> Row { get; set; }
    }

    [XmlRoot(ElementName = "result")]
    public class Result
    {
        [XmlElement(ElementName = "rows")]
        public Rows Rows { get; set; }
    }

    [XmlRoot(ElementName = "response")]
    public class Response
    {
        [XmlElement(ElementName = "result")]
        public Result Result { get; set; }
        [XmlAttribute(AttributeName = "uri")]
        public string Uri { get; set; }
        [XmlAttribute(AttributeName = "action")]
        public string Action { get; set; }
    }

Then use the deserialization code like the following

//here I'm trying to load the file from the disk but you can do the same by passing a string 

  Response  model;

            var xml = File.ReadAllText("file.xml");  
            using (TextReader reader = new StringReader(xml))
            {
                System.Xml.Serialization.XmlSerializer deserializer = new System.Xml.Serialization.XmlSerializer(typeof(Response));
                model = (Response)deserializer.Deserialize(reader);
            }   

More you can access your rows like this

var rows = model.Result.Rows; 

//hope this can help

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

3 Comments

Thanks for your response, I already changed my code for what you propose, but I still get the same error, any idea why still happening? thanks.
I should guess that the XML you have posted is not complete because I have tried it and it works could you please post the full XML to reproduce the issue
Didn't notice that I was using a Regrex to remove spaces, that was the problem, now it works, thanks a lot!
0

When I run your code I get the following exception.

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

InnerException

InvalidOperationException: < response xmlns='' > was not expected.

This is because you must define the outer most element as the root element and not one deeper in the structure like your tried to do. One way to solve this is by defining all nessesary model classes like @BRAHIM Kamel did.


Ïf you don't want to have so many model classes and you don't care to much about performance you could also do this.

[XmlRoot("row")]
public class ModelXML
{
    public class Column
    {
        [XmlAttribute("name")]
        public string Name { set; get; }
        [XmlText]
        public string Value { set; get; }
    }

    [XmlElement("column")]
    public List<Column> Columns { get; set; }
}

IEnumerable<T> Deserialize<T>(IEnumerable<XElement> elements)
{
    foreach (var element in elements)
    {
        using (var reader = XDocument.Parse(element.ToString()).CreateReader())
        {
            XmlSerializer deserializer = new XmlSerializer(typeof(T));
            yield return (T)deserializer.Deserialize(reader);
        }
    }
}

var document = XDocument.Parse(xml_str);
var collection = Deserialize<ModelXML>(
    document.XPathSelectElements("response/result/rows/row"));

Comments

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.