Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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>
like image 769
Klemikaze Avatar asked Jul 21 '26 14:07

Klemikaze


2 Answers

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:

  • Use custom serialization (IXmlSerializable), see: http://www.codeproject.com/Articles/43237/How-to-Implement-IXmlSerializable-Correctly
  • Do post editing of the serialized file and do a string replace with the desired node names

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

like image 79
DerApe Avatar answered Jul 23 '26 03:07

DerApe


[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.

like image 39
Anton Gudin Avatar answered Jul 23 '26 05:07

Anton Gudin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!