XmlSerializer.跳过xml未知节点 [英] XmlSerializer. Skip xml unknown node

查看:27
本文介绍了XmlSerializer.跳过xml未知节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在反序列化我的 xml 文件时遇到问题.让我们假装我们有一个 xml 文件和一个用于反序列化的类.

I have a problem with deserialization of my xml files. Let's pretend that we have a xml file and a class that we are using for deserialization to.

例如:

xml -

<dataStore>
  <name>newDataStore1</name>
  <description>sdffasdfasdf</description>
  <type>Shapefile</type>
  <enabled>false</enabled>
  <workspace>
    <name>newTestWorkspace</name>
    <atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="alternate" href="ht
tp://192.168.6.71:8080/geoserver/rest/workspaces/newTestWorkspace.xml" type="app
lication/xml"/>
  </workspace>
  <connectionParameters>
    <entry key="memory mapped buffer">false</entry>
    <entry key="create spatial index">true</entry>
    <entry key="charset">ISO-8859-1</entry>
    <entry key="filetype">shapefile</entry>
    <entry key="cache and reuse memory maps">true</entry>
    <entry key="url">file:data/shapefiles/states.shp</entry>
    <entry key="namespace">http://www.opengeospatial.net/cite</entry>
  </connectionParameters>
  <__default>false</__default>
  <featureTypes>
    <atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="alternate" href="ht
tp://192.168.6.71:8080/geoserver/rest/workspaces/newTestWorkspace/datastores/new
DataStore1/featuretypes.xml" type="application/xml"/>
  </featureTypes>
</dataStore>

namespace GeoServerApiTester
{


    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.225")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlRootAttribute("dataStore", Namespace="", IsNullable=false)]
    public partial class DataStore
    {

        private string nameField;

        private string typeField;

        private bool enabledField;

        private WorkSpacePreview workspaceField;

        private ConnectionParametersStorageEntryCollection connectionParametersField;

        private string @__defaultField;

        private LinkCollection featureTypesField;

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=0, ElementName="name")]
        public string Name
        {
            get
            {
                return this.nameField;
            }
            set
            {
                this.nameField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=1, ElementName="type")]
        public string Type
        {
            get
            {
                return this.typeField;
            }
            set
            {
                this.typeField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=2, ElementName="enabled")]
        public bool Enabled
        {
            get
            {
                return this.enabledField;
            }
            set
            {
                this.enabledField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Order=3, ElementName="workspace")]
        public WorkSpacePreview Workspace
        {
            get
            {
                return this.workspaceField;
            }
            set
            {
                this.workspaceField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlArrayAttribute(Order=4, ElementName="connectionParameters")]
        [System.Xml.Serialization.XmlArrayItemAttribute("entry", Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=false)]
        public ConnectionParametersStorageEntryCollection ConnectionParameters
        {
            get
            {
                return this.connectionParametersField;
            }
            set
            {
                this.connectionParametersField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=5)]
        public string @__default
        {
            get
            {
                return this.@__defaultField;
            }
            set
            {
                this.@__defaultField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlArrayAttribute(Order=6, ElementName="featureTypes")]
        [System.Xml.Serialization.XmlArrayItemAttribute("link", Namespace="http://www.w3.org/2005/Atom", IsNullable=false)]
        public LinkCollection FeatureTypes
        {
            get
            {
                return this.featureTypesField;
            }
            set
            {
                this.featureTypesField = value;
            }
        }

        public virtual bool ShouldSerializeConnectionParameters()
        {
            return ((this.ConnectionParameters != null) 
                        && (this.ConnectionParameters.Count > 0));
        }

        public virtual bool ShouldSerializeFeatureTypes()
        {
            return ((this.FeatureTypes != null) 
                        && (this.FeatureTypes.Count > 0));
        }
    }
}

您可以看到该类不包含描述字段.

You can see that the class doesn't contain description field.

<dataStore>
  <name>newDataStore1</name>
  <enabled>false</enabled>
</dataStore>

可以看到,描述之后的所有元素都没有被反序列化.

You can see that all elements after description were not be deserialized.

当程序获取 xml 内容并且此 xml 包含不在类中的元素时,此元素之后的所有元素都不会被反序列化.

When program gets xml content and this xml contains an element that isn't in the class all elements after this element won't be desirialized.

如何在反序列化过程中跳过未知元素并获得如下结果:

How can I skip unknown element during deserialization and get something like this:

<dataStore>
  <name>newDataStore1</name>

  <type>Shapefile</type>
  <enabled>false</enabled>
  <workspace>
    <name>newTestWorkspace</name>
    <atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="alternate" href="ht
tp://192.168.6.71:8080/geoserver/rest/workspaces/newTestWorkspace.xml" type="app
lication/xml"/>
  </workspace>
  <connectionParameters>
    <entry key="memory mapped buffer">false</entry>
    <entry key="create spatial index">true</entry>
    <entry key="charset">ISO-8859-1</entry>
    <entry key="filetype">shapefile</entry>
    <entry key="cache and reuse memory maps">true</entry>
    <entry key="url">file:data/shapefiles/states.shp</entry>
    <entry key="namespace">http://www.opengeospatial.net/cite</entry>
  </connectionParameters>
  <__default>false</__default>
  <featureTypes>
    <atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="alternate" href="ht
tp://192.168.6.71:8080/geoserver/rest/workspaces/newTestWorkspace/datastores/new
DataStore1/featuretypes.xml" type="application/xml"/>
  </featureTypes>
</dataStore>

只删除元素

推荐答案

默认情况下,XmlSerializer 会忽略未知节点(元素也是如此).现在,当您像这样使用 Order 属性时,您是在明确说明要序列化/反序列化的 Order.

By default the XmlSerializer ignores unknown nodes (so elements as well). Now when you use the Order property like you do, you are telling explicitly in which Order to serialize/deserialize.

因此,当 XmlSerializer 出现在您的 description 元素上时,它就变成了一个未知元素,因为它需要 type 元素.其余的也将作为未知元素受到威胁,因为它们不再映射到您指定的顺序.例如,当涉及到 XML 中索引为 2 的 type 元素时,它期望它是 enabled 元素,因此该元素也变得未知.

So when the XmlSerializer comes to your description element this becomes a unknown element because it expects the type element. The rest will also be threated as unknown elements because they do not map anymore to your specified order. For example when it comes to your type element which has index two in your XML, it expects it be the enabled element so this element becomes unknown as well.

您可以通过处理 UnknownNode XmlSerializer 类的事件.它将为遇到的每个未知节点触发此事件.

You can check this behaviour by handling the UnknownNode event of the XmlSerializer class. This event will be fired for every unknown node it encounters.

如何进行?如果排序没有意义,请不要使用它.在某些情况下,使用排序确实有意义.我多次看到的一个经典示例是(遗留)应用程序,它将 XML 文档视为字符串并从上到下读取所有元素.

How to proceed? If the ordering has no meaning don't use it. There are situations where it does make sense to use ordering. A classical example I've seen multiple times are (legacy) apps which treat XML documents as strings and read all the elements from top to bottom.

另一种选择是实现 IXmlSerializer 接口,它为您提供更好地控制对象的序列化和反序列化方式.

Another option would be implementing the IXmlSerializer interface, which gives you better control on how your object is serialized and deserialized.

这篇关于XmlSerializer.跳过xml未知节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆