Klemikaze
Klemikaze

Reputation: 378

XMLSerializer changes name of elements

I'm trying to serialize object for import to another Software and the issue is, that elements in XML that is to be imported contain ":" (p.e.: < ftr:filter>).
I declared classes overriding those names with [XmlAttribute("ftr:filter")] and [XMLElement(ftr:differentFilter")], but serializer products different nodes. I bet it has something to do with encoding, but I'm not able to change the result (thought I changed encoding).
Example of classes:

public class ListPrijemkaRequest
{
    [XmlAttribute("version")]
    public string Version { get; set; }
    [XmlAttribute("prijemkaVersion")]
    public string PrijemkaVersion { get; set; }
    [XmlElement("lst:requestPrijemka")]
    public List<RequestPrijemka> Requests { get; set; }
}

public class RequestPrijemka
{
    [XmlElement("ftr:filter")]
    public RequestDateFilter Filter { get; set; }
}

Desired ooutput:

< lst:listPrijemkaRequest version="2.0" prijemkaVersion="2.0">
    < lst:requestPrijemka>
        < ftr:filter>
            < ftr:dateFrom>2013-01-10</ftr:dateFrom>
            < ftr:dateTill>2013-03-30</ftr:dateTill>
        < /ftr:filter>
    < /lst:requestPrijemka>
< /lst:listPrijemkaRequest>

Obtained output:

< lst_x003A_listPrijemkaRequest version="2.0" prijemkaVersion="2.0">
    < lst_x003A_requestPrijemka>
        < ftr_x003A_filter>
            < ftr_x003A_dateFrom>2013-01-10</ftr_x003A_dateFrom>
            < ftr_x003A_dateTill>2013-03-30</ftr_x003A_dateTill>
        < /ftr_x003A_filter>
    < /lst_x003A_requestPrijemka>
< /lst_x003A_listPrijemkaRequest>

Upvotes: 3

Views: 2802

Answers (2)

Anton Gudin
Anton Gudin

Reputation: 31

[XmlRoot("listPrijemkaRequest", Namespace = "http://your.companies.namespace/lst")]
public class ListPrijemkaRequest {
    [XmlAttribute("version")]
    public string Version { get; set; }
    [XmlAttribute("prijemkaVersion")]
    public string PrijemkaVersion { get; set; }
    [XmlElement("requestPrijemka")]
    public List<RequestPrijemka> Requests { get; set; }
}

public class RequestDateFilter
{
    [XmlElement(ElementName = "dateFrom")]
    public DateTime DateFrom { get; set; }

    [XmlElement(ElementName = "dateTill")]
    public DateTime DateTill { get; set; }
}

public class RequestPrijemka {
    [XmlElement("filter", Namespace = "http://your.companies.namespace/ftr")]
    public RequestDateFilter Filter { get; set; }
}

static class Program {
    static void Main() {
        var ns = new XmlSerializerNamespaces();
        ns.Add("lst", "http://your.companies.namespace/lst");
        ns.Add("ftr", "http://your.companies.namespace/ftr");
        var xser = new XmlSerializer(typeof(ListPrijemkaRequest));

        var obj = new ListPrijemkaRequest
            {
                Version = "2.0",
                PrijemkaVersion = "2.0",
                Requests = new List<RequestPrijemka>
                    {
                        new RequestPrijemka
                            {
                                Filter = new RequestDateFilter {DateFrom = DateTime.Now, DateTill = DateTime.Now}
                            }
                    }
            };

        xser.Serialize(Console.Out, obj, ns);
        Console.ReadLine();
    }
}

Produce this xml:

<?xml version="1.0" encoding="cp866"?>
<lst:listPrijemkaRequest xmlns:ftr="http://your.companies.namespace/ftr" version="2.0" prijemkaVersion="2.0" xmlns:lst="http://your.companies.namespace/lst">
  <lst:requestPrijemka>
    <ftr:filter>
      <ftr:dateFrom>2014-07-17T16:17:47.0601039+03:00</ftr:dateFrom>
      <ftr:dateTill>2014-07-17T16:17:47.061104+03:00</ftr:dateTill>
    </ftr:filter>
  </lst:requestPrijemka>
</lst:listPrijemkaRequest>

Looks similar with what you need.

Upvotes: 2

DerApe
DerApe

Reputation: 3175

If those "tags" ftr / lst are namespaces, there is no need to "hard-code" them, you can setup the serializer to use those namespaces.

http://msdn.microsoft.com/en-us/library/ms163161%28v=vs.110%29.aspx

Example (taken from XML Serialization and namespace prefixes)

[XmlRoot("Node", Namespace="http://your.companies.namespace")]
public class ListPrijemkaRequest {
    [XmlElement("requestPrijemka")]
    public List<RequestPrijemka> Requests { get; set; }
}

static class Program
{
    static void Main()
    {
        XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
        ns.Add("lst", "http://your.companies.namespace");
        XmlSerializer xser = new XmlSerializer(typeof(ListPrijemkaRequest));
        xser.Serialize(Console.Out, new ListPrijemkaRequest(), ns);
    }
}

If not, I don't think it's possible with "default" serialization.

Other options:

But like I said in my comment, it is not recommended to use : in node names in the first place!

Upvotes: 4

Related Questions