以编程方式控制 xml 元素的顺序

Posted

技术标签:

【中文标题】以编程方式控制 xml 元素的顺序【英文标题】:Programmatically controlling the order of xml elements 【发布时间】:2011-10-09 06:01:06 【问题描述】:

我在我的 .Net 应用程序中使用第三方网络服务 [WS]。 我的应用程序正在使用从这个 WS 的 wsdl 生成的实体类。 我从 db 中获取数据,将其填充到实体对象中,然后使用 XmlSerializer 类从中生成一个 xml。

WS 的其中一种方法需要此 xml 字符串作为输入。并且 xml 应该具有与 WS 预期的顺序相同的元素。但是发生的事情是一些元素在我的应用程序中颠倒了,并且所以 WS 在序列化上抛出了一个最里面的异常:。 _innerException “不一致的顺序:如果用于类的成员之一,所有类粒子成员都需要'Order'属性,请使用类成员的XmlElement,XmlAnyElement或XmlArray自定义属性显式设置'Order''仪器'。" System.Exception System.InvalidOperationException

XmlSerializer serializer = new XmlSerializer(typeof(totemmessage));

所以,我的问题是,在将这些 xml 元素发送到 WS 之前,如何以编程方式控制这些 xml 元素在我的应用程序中的顺序?注意:我不想为此目的使用 xslt。

感谢阅读。

这是我的实体类:

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] 
    [System.SerializableAttribute()] 
    [System.Diagnostics.DebuggerStepThroughAttribute()] 
    [System.ComponentModel.DesignerCategoryAttribute("code")] 
    [System.Xml.Serialization.XmlTypeAttribute(TypeName="totem-message")] 
    [System.Xml.Serialization.XmlRootAttribute("totem", Namespace="", IsNullable=false)] 
    public partial class totemmessage   

        private object itemField; 

        private ItemChoiceType1 itemElementNameField; 

        /// <remarks/> 
        [System.Xml.Serialization.XmlElementAttribute("error", typeof(errorinfo))] 
        [System.Xml.Serialization.XmlElementAttribute("parseReport", typeof(parseReportinfo))] 
        [System.Xml.Serialization.XmlElementAttribute("results", typeof(templateinfo))] 
        [System.Xml.Serialization.XmlElementAttribute("subareas", typeof(subareasinfo))] 
        [System.Xml.Serialization.XmlElementAttribute("template", typeof(templateinfo))] 
        [System.Xml.Serialization.XmlElementAttribute("upload", typeof(templateinfo))] 
        [System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemElementName")] 
        [System.Xml.Serialization.XmlElement(Order = 0)]       
        public object Item  
            get  
                return this.itemField; 
             
            set  
                this.itemField = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 1)] 
        [System.Xml.Serialization.XmlIgnoreAttribute()] 
        public ItemChoiceType1 ItemElementName  
            get  
                return this.itemElementNameField; 
             
            set  
                this.itemElementNameField = value; 
             
                

    

[System.Xml.Serialization.XmlIncludeAttribute(typeof(energyInstrument))] 
    [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] 
    [System.SerializableAttribute()] 
    [System.Diagnostics.DebuggerStepThroughAttribute()] 
    [System.ComponentModel.DesignerCategoryAttribute("code")] 
    public abstract partial class abstractEnergyInstrument  

        private energyContractTime periodField; 

        private bool periodFieldSpecified; 

        private System.DateTime startDateField; 

        private bool startDateFieldSpecified; 

        private System.DateTime endDateField; 

        private bool endDateFieldSpecified; 

        private System.DateTime expiryDateField; 

        private bool expiryDateFieldSpecified; 

        private energyInstrumentClassifier typeField; 

        private bool typeFieldSpecified; 

        private string strikeField; 

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 0)] 
        public energyContractTime period  
            get  
                return this.periodField; 
             
            set  
                this.periodField = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 1)] 
        [System.Xml.Serialization.XmlIgnoreAttribute()]        
        public bool periodSpecified  
            get  
                return this.periodFieldSpecified; 
             
            set  
                this.periodFieldSpecified = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElementAttribute(DataType="date", Order =2)]        
        public System.DateTime startDate  
            get  
                return this.startDateField; 
             
            set  
                this.startDateField = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 3)] 
        [System.Xml.Serialization.XmlIgnoreAttribute()]        
        public bool startDateSpecified  
            get  
                return this.startDateFieldSpecified; 
             
            set  
                this.startDateFieldSpecified = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElementAttribute(DataType="date", Order =4)]        
        public System.DateTime endDate  
            get  
                return this.endDateField; 
             
            set  
                this.endDateField = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 5)] 
        [System.Xml.Serialization.XmlIgnoreAttribute()]        
        public bool endDateSpecified  
            get  
                return this.endDateFieldSpecified; 
             
            set  
                this.endDateFieldSpecified = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElementAttribute(DataType="date", Order =6)]        
        public System.DateTime expiryDate  
            get  
                return this.expiryDateField; 
             
            set  
                this.expiryDateField = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 7)] 
        [System.Xml.Serialization.XmlIgnoreAttribute()]        
        public bool expiryDateSpecified  
            get  
                return this.expiryDateFieldSpecified; 
             
            set  
                this.expiryDateFieldSpecified = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 8)] 
        public energyInstrumentClassifier type  
            get  
                return this.typeField; 
             
            set  
                this.typeField = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 9)] 
        [System.Xml.Serialization.XmlIgnoreAttribute()]        
        public bool typeSpecified  
            get  
                return this.typeFieldSpecified; 
             
            set  
                this.typeFieldSpecified = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 10)] 
        public string strike  
            get  
                return this.strikeField; 
             
            set  
                this.strikeField = value; 
             
         
    

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] 
    [System.SerializableAttribute()] 
    [System.Diagnostics.DebuggerStepThroughAttribute()] 
    [System.ComponentModel.DesignerCategoryAttribute("code")] 
    [System.Xml.Serialization.XmlRootAttribute("instrument", Namespace="", IsNullable=false)] 
    public partial class energyInstrument : abstractEnergyInstrument  

        private decimal priceField; 

        private bool priceFieldSpecified; 

        private decimal forwardField; 

        private bool forwardFieldSpecified; 

        private decimal volField; 

        private bool volFieldSpecified; 

        private decimal consensusPriceField; 

        private bool consensusPriceFieldSpecified; 

        private decimal compositePriceField; 

        private bool compositePriceFieldSpecified; 

        private decimal reconstitutedForwardField; 

        private bool reconstitutedForwardFieldSpecified; 

        private decimal consensusVolField; 

        private bool consensusVolFieldSpecified; 

        private decimal compositeVolField; 

        private bool compositeVolFieldSpecified; 

        private string priceOutField; 

        private decimal priceRangeField; 

        private bool priceRangeFieldSpecified; 

        private decimal priceStddevField; 

        private bool priceStddevFieldSpecified; 

        private string volOutField; 

        private decimal volRangeField; 

        private bool volRangeFieldSpecified; 

        private decimal volStddevField; 

        private bool volStddevFieldSpecified; 

        private string contributorsField; 

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 0)] 
        public decimal price  
            get  
                return this.priceField; 
             
            set  
                this.priceField = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 1)] 
        [System.Xml.Serialization.XmlIgnoreAttribute()]        
        public bool priceSpecified  
            get  
                return this.priceFieldSpecified; 
             
            set  
                this.priceFieldSpecified = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 2)] 
        public decimal forward  
            get  
                return this.forwardField; 
             
            set  
                this.forwardField = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 3)] 
        [System.Xml.Serialization.XmlIgnoreAttribute()]        
        public bool forwardSpecified  
            get  
                return this.forwardFieldSpecified; 
             
            set  
                this.forwardFieldSpecified = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 4)] 
        public decimal vol  
            get  
                return this.volField; 
             
            set  
                this.volField = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 5)] 
        [System.Xml.Serialization.XmlIgnoreAttribute()]        
        public bool volSpecified  
            get  
                return this.volFieldSpecified; 
             
            set  
                this.volFieldSpecified = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 6)] 
        public decimal consensusPrice  
            get  
                return this.consensusPriceField; 
             
            set  
                this.consensusPriceField = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 7)] 
        [System.Xml.Serialization.XmlIgnoreAttribute()]        
        public bool consensusPriceSpecified  
            get  
                return this.consensusPriceFieldSpecified; 
             
            set  
                this.consensusPriceFieldSpecified = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 8)] 
        public decimal compositePrice  
            get  
                return this.compositePriceField; 
             
            set  
                this.compositePriceField = value; 
             
         

        /// <remarks/>        
        [System.Xml.Serialization.XmlElement(Order = 9)] 
        [System.Xml.Serialization.XmlIgnoreAttribute()]        
        public bool compositePriceSpecified  
            get  
                return this.compositePriceFieldSpecified; 
             
            set  
                this.compositePriceFieldSpecified = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 10)] 
        public decimal reconstitutedForward  
            get  
                return this.reconstitutedForwardField; 
             
            set  
                this.reconstitutedForwardField = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 11)] 
        [System.Xml.Serialization.XmlIgnoreAttribute()]        
        public bool reconstitutedForwardSpecified  
            get  
                return this.reconstitutedForwardFieldSpecified; 
             
            set  
                this.reconstitutedForwardFieldSpecified = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 12)] 
        public decimal consensusVol  
            get  
                return this.consensusVolField; 
             
            set  
                this.consensusVolField = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 13)] 
        [System.Xml.Serialization.XmlIgnoreAttribute()]        
        public bool consensusVolSpecified  
            get  
                return this.consensusVolFieldSpecified; 
             
            set  
                this.consensusVolFieldSpecified = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 14)] 
        public decimal compositeVol  
            get  
                return this.compositeVolField; 
             
            set  
                this.compositeVolField = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 15)] 
        [System.Xml.Serialization.XmlIgnoreAttribute()]        
        public bool compositeVolSpecified  
            get  
                return this.compositeVolFieldSpecified; 
             
            set  
                this.compositeVolFieldSpecified = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 16)] 
        public string priceOut  
            get  
                return this.priceOutField; 
             
            set  
                this.priceOutField = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 17)] 
        public decimal priceRange  
            get  
                return this.priceRangeField; 
             
            set  
                this.priceRangeField = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 18)] 
        [System.Xml.Serialization.XmlIgnoreAttribute()]        
        public bool priceRangeSpecified  
            get  
                return this.priceRangeFieldSpecified; 
             
            set  
                this.priceRangeFieldSpecified = value; 
             
         

        /// <remarks/>

        [System.Xml.Serialization.XmlElement(Order = 19)] 
        public decimal priceStddev 
         
            get  
                return this.priceStddevField; 
             
            set  
                this.priceStddevField = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 20)] 
        [System.Xml.Serialization.XmlIgnoreAttribute()]        
        public bool priceStddevSpecified  
            get  
                return this.priceStddevFieldSpecified; 
             
            set  
                this.priceStddevFieldSpecified = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 21)] 
        public string volOut  
            get  
                return this.volOutField; 
             
            set  
                this.volOutField = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 22)] 
        public decimal volRange  
            get  
                return this.volRangeField; 
             
            set  
                this.volRangeField = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 23)] 
        [System.Xml.Serialization.XmlIgnoreAttribute()]        
        public bool volRangeSpecified  
            get  
                return this.volRangeFieldSpecified; 
             
            set  
                this.volRangeFieldSpecified = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 24)] 
        public decimal volStddev  
            get  
                return this.volStddevField; 
             
            set  
                this.volStddevField = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElement(Order = 25)] 
        [System.Xml.Serialization.XmlIgnoreAttribute()]        
        public bool volStddevSpecified  
            get  
                return this.volStddevFieldSpecified; 
             
            set  
                this.volStddevFieldSpecified = value; 
             
         

        /// <remarks/> 
        [System.Xml.Serialization.XmlElementAttribute(DataType="integer", Order =26)]        
        public string contributors  
            get  
                return this.contributorsField; 
             
            set  
                this.contributorsField = value; 
             
         
    

【问题讨论】:

【参考方案1】:

我在实体类中的每个属性之上使用了 XmlElement[Order =n]。所以,在玩弄了排序之后,我可以使这个序列化工作。继承和部分类使这个修复变得更加困难!谢谢。

【讨论】:

【参考方案2】:

XmlSerializer 按类中的声明顺序生成元素 - 你能改变实体中的顺序吗?

【讨论】:

我做到了。但行为仍然相同。谢谢。 您能否将类定义和序列化的 XML 添加到您的问题中,以便我们了解更多细节? 好的。只是一个简单的问题。Order 属性值是从 0 开始还是从 1 开始?谢谢。 如果它像 DataMember 一样工作(我怀疑它会这样),那么确切的值并不重要 - 较高的值在较低的值之后 好的..我从 1 开始给了订单,它给了我一个错误,说“在序列化过程中有一个错误反映属性'项目'”。所以我认为可能是订单从 0 开始。无论如何,我现在尝试将 order 设置为 0。谢谢【参考方案3】:

如何将Order = N 与其他 XML 属性和 List 集合一起使用。

public class MyClass

   [XmlAnyElement("My-XLMComment", Order = 3)] public XmlComment CommentA  get; set;  = new XmlDocument().CreateComment("This is an XML comment");
   [XmlAttribute("MyAttribute")] public string str4  get; set;  //This is a XML-Attribute, Order not applicable
   [XmlIgnore] public string str1  get; set;  //This is a [XmlIgnore], Order not applicable
   [XmlElement(Order = 5)] public string str2  get; set;  // Standard property with Order    
   [XmlElement(Order = 2)] public string str3  get; set;  // Standard property with Order    
   [XmlElement(Order = 1)] public List<MyList> ListElms = new List<MyList> //List collection with Order
   
      new ListElm str1 = "xxx", str2 ="yyy", str3 ="zzz" ,
      new ListElm str1 = "xxx", str2 ="yyy", str3 ="zzz"
   ;

   public class MyList
   
      [XmlElement(Order = 3)] public string str1  get; set;  // Order can be assigned, but not mandatory 
      [XmlElement(Order = 2)] public string str2  get; set;  // Order can be assigned, but not mandatory
      [XmlElement(Order = 1)] public string str3  get; set;  // Order can be assigned, but not mandatory
   

将序列化为:

<MyClass MyAttribute="str4">
    <ListElms>
       <str3>zzz</str3>
       <str2>yyy</str2>
       <str1>xxx</str1>
    </ListElms>
    <ListElms>
       <str3>zzz</str3>
       <str2>yyy</str2>
       <str1>xxx</str1>
    </ListElms>
       <str3>str3</str3>
       <!--This is an XML comment-->
       <str2>str2</str2>
</MyClass>

【讨论】:

以上是关于以编程方式控制 xml 元素的顺序的主要内容,如果未能解决你的问题,请参考以下文章

如何规范 XML 元素和属性的顺序?

Chrome 开发工具控制台 - 以编程方式选择框架

我可以以编程方式控制 WCF 跟踪吗?

以编程方式为水平居中的元素提供偏移量

在带有 XIB 的视图控制器上以编程方式初始化 UISegmentedControl

如何以编程方式找到特定的 XML 元素?