使用C#/ .NET反序列化XML时跳过包装元素

时间:2015-06-03 19:23:58

标签: c# .net xml deserialization xml-deserialization

我正在尝试使用C#/ .NET 3.5反序列化传入的XML数据,使用以标记为XmlRoot的类开头的类层次结构,并包含具有所需属性的类和成员。到目前为止这是有效的。

现在我遇到的输入数据大致如下:

<?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>

最外面的两个元素 - ns1:foons1:bar - 是我无法控制的远程系统中序列化过程的结果。它们总是存在于完全相同的星座中,并且没有任何意义。

按照我目前的方法,我可以写一个引用class Foo的{​​{1}},后者又会引用class Bar。但是,由于我对class Payloadfoo元素不感兴趣,有没有办法在反序列化期间跳过它们并让Deserializer只返回有效负载?如果不是:是否可以使用bar属性生成class FooPayload,但之后会以某种方式跳过XmlRoot(ElementName = "foo", Namespace = "http://some.name/space")bar级别,直接payload类包含名为FooPayloadInteresting

的属性

1 个答案:

答案 0 :(得分:-2)

我修改了您的XML以纠正错误。请参阅下面的有趣解决方案。

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; }
    }
}
​