简体   繁体   中英

Skip wrapping elements when deserializing XML with C# / .NET

I am trying to deserialize incoming XML data with C#/.NET 3.5 using a class hierarchy that starts with a class tagged as XmlRoot and contains classes and members with the required attributes. This works so far.

Now I have come across input data that looks approximately like this:

<?xml version="1.0" encoding="UTF-8"?>
<ns1:foo xmlns:ns1="http://some.name/space">
  <ns1:bar>
    <payload interesting="true">
      <stuff type="interesting"/>
    </payload>
  </ns1:bar>
</ns1:foo>

The outermost two elements - ns1:foo and ns1:bar - are results of the serialization process in the remote system that I have no control over. They always exist in exactly the same constellation and are of no interest whatsoever.

Following my current approach, I could write a class Foo that references a class Bar which in turn references the class Payload . However, since I'm not interested in the foo and bar elements, is there a way to skip them during the deserialization and have the Deserializer return only the payload? If not: Is it possible to make a class FooPayload with an XmlRoot(ElementName = "foo", Namespace = "http://some.name/space") attribute, but then somehow skip the bar and payload levels so that the FooPayload class directly contains properties named Interesting and Stuff ?

I modified your XML to correct for errors. See interesting solution below.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using System.Text.RegularExpressions;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string input =
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
                "<ns1:foo xmlns:ns1=\"http://some.name/space\">" +
                  "<ns1:bar>" +
                    "<ns1:payload interesting=\"true\">" +
                      "<ns1:stuff type=\"interesting\"/>" +
                    "</ns1:payload>" +
                  "</ns1:bar>" +
                "</ns1:foo>";

            //remove prefix
            string pattern = "(</?)([^:]*:)";
            Regex expr = new Regex(pattern);
            input = expr.Replace(input, "$1");

            XmlSerializer xs = new XmlSerializer(typeof(Foo));
            StringReader s_reader = new StringReader(input);
            XmlTextReader reader = new XmlTextReader(s_reader);
            Foo  foo = (Foo)xs.Deserialize(reader);
            foo.GetStuff();
        }
    }
    [XmlRoot(ElementName = "foo")]
    public class Foo
    {
        [XmlElement("bar")]
        public Bar bar { get; set; }

        private Boolean interesting;
        private string type;

        public void GetStuff()
        {
            interesting = bar.payload.interesting;
            type = bar.payload.stuff.type;
        }

    }
    [XmlRoot("bar")]
    public class Bar
    {
        [XmlElement("payload")]
        public Payload payload { get; set; }
    }
    [XmlRoot("payload")]
    public class Payload
    {
        [XmlAttribute("interesting")]
        public Boolean interesting { get; set; }
        [XmlElement("stuff")]
        public Stuff stuff { get; set; }
    }
    [XmlRoot("stuff")]
    public class Stuff
    {
        [XmlAttribute("type")]
        public string type { get; set; }
    }
}
​

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM