簡體   English   中英

如何在C#中的XML序列化期間替換XML元素?

[英]How to alternate XML Elements during XML serialization in C#?

我有一個由數據提供者提供給我們的XSD架構。 我不能修改它。 我使用XSD.exe命令行工具生成了類。 對於它完美運行的一切,我可以用C#創建我的對象,用XML序列化它並根據XSD驗證它。

我有一小部分問題。 預期的產出是:

    <Physical>
        <Class>P</Class>
        <Capacity>14</Capacity>
        <Class>J</Class>
        <Capacity>64</Capacity>
        <Class>W</Class>
        <Capacity>1</Capacity>
        <Class>Y</Class>
        <Capacity>2</Capacity>
    </Physical>
    <Saleable Protected="true">
        <Class>P</Class>
        <Capacity>14</Capacity>
        <Class>J</Class>
        <Capacity>64</Capacity>
        <Class>W</Class>
        <Capacity>1</Capacity>
        <Class>Y</Class>
        <Capacity>2</Capacity>
    </Saleable>

正如您所看到的,Physical和Sealable的子元素是備用的(即Class,然后是Capacity,然后是Class,然后是Capacity等)。

這是由XSD.exe生成的類的代碼:

public partial class ClassA
{
    private string[] classField;

    private Integerctype[] capacityField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("Class", DataType = "token")]
    public string[] Class
    {
        get
        {
            return this.classField;
        }
        set
        {
            this.classField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("Capacity", IsNullable = true)]
    public Integerctype[] Capacity
    {
        get
        {
            return this.capacityField;
        }
        set
        {
            this.capacityField = value;
        }
    }
}

並且序列化后我收到的輸出:

<Physical>
    <Class>P</Class>
    <Class>J</Class>
    <Class>W</Class>
    <Class>Y</Class>
    <Capacity>14</Capacity>
    <Capacity>64</Capacity>
    <Capacity>1</Capacity>
    <Capacity>2</Capacity>
</Physical>
<Saleable>
    <Class>P</Class>
    <Class>J</Class>
    <Class>W</Class>
    <Class>Y</Class>
    <Capacity>14</Capacity>
    <Capacity>64</Capacity>
    <Capacity>1</Capacity>
    <Capacity>2</Capacity>
</Saleable>

如您所見,我們失去了Class和Capacity之間的交替......

我試圖使用XmlElementAttribute的Order屬性:Class屬性用Order = 1裝飾,而Capacity屬性用Order = 2裝飾,但它沒有幫助。 例:

[System.Xml.Serialization.XmlElementAttribute("Class", DataType = "token", Order = 1)]
public string[] Class

在驗證期間,無論是否有Order屬性,我都會收到如下錯誤:

名稱空間“xxx”中的“Physical”元素在名稱空間“xxx”中具有無效的子元素“Class”。 期望的可能元素列表:命名空間'xxx'中的'容量'。

最后,這是XSD的一部分:

<xsd:element name="ClassA" minOccurs="0">
    <xsd:complexType>
        <xsd:all>
            <xsd:element name="Physical" minOccurs="0">
                <xsd:annotation>
                    <xsd:documentation>True, physical class A configuration</xsd:documentation>
                </xsd:annotation>
                <xsd:complexType>
                    <xsd:sequence minOccurs="0" maxOccurs="unbounded">
                        <xsd:element name="Class" type="CabinClass.type" />
                        <xsd:element name="Capacity" type="Integer.ctype" nillable="true" />
                    </xsd:sequence>
                    <xsd:attributeGroup ref="Array.attgroup" />
                </xsd:complexType>
            </xsd:element>
            <xsd:element name="Saleable" minOccurs="0">
                <xsd:annotation>
                    <xsd:documentation>Class A configuration for sales purposes</xsd:documentation>
                </xsd:annotation>
                <xsd:complexType>
                    <xsd:sequence minOccurs="0" maxOccurs="unbounded">
                        <xsd:element name="Class" type="CabinClass.type" />
                        <xsd:element name="Capacity" type="Integer.ctype" nillable="true" />
                    </xsd:sequence>
                    <xsd:attributeGroup ref="Array.attgroup" />
                </xsd:complexType>
            </xsd:element>
        </xsd:all>
        <xsd:attributeGroup ref="Container.attgroup" />
    </xsd:complexType>
</xsd:element>

我的猜測是它與xsd:sequence的存在有關。 但正如我所說,我不想修改由數據提供者提供的XSD,我們必須確保我們生成的XML完全兼容。

不知道怎樣才能解決這個問題?

簡化的代碼可能是這樣的:

public class Physical
{
    [XmlElement("Capacity", typeof(int))]
    [XmlElement("Class", typeof(string))]
    public object[] Items { get; set; }
}

這將確保正確的反序列化,並按照它們在數組中的順序給出元素的序列化。

工作版本可能如下所示:

public class Physical
{
    [EditorBrowsable(EditorBrowsableState.Never)]
    [XmlElement("Capacity", typeof(int))]
    [XmlElement("Class", typeof(string))]
    public object[] Items
    {
        get
        {
            object[] items = new object[Class.Length * 2];
            for (int i = 0; i < items.Length; i += 2)
            {
                items[i] = Class[i / 2];
                items[i + 1] = Capacity[i / 2];
            }
            return items;
        }
        set
        {
            Class = new string[value.Length / 2];
            Capacity = new int[value.Length / 2];
            for (int i = 0; i < value.Length; i += 2)
            {
                Class[i / 2] = (string)value[i];
                Capacity[i / 2] = (int)value[i + 1];
            }
        }
    }

    [XmlIgnore]
    public string[] Class { get; set; }
    [XmlIgnore]
    public int[] Capacity { get; set; }
}

int更改為Integerctype ,添加DataType參數。

同樣,更改第二個類。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM