2014-06-25 33 views
0

我有像索引條目的XML文件:的Xml序列化/反序列化索引條目

<xml> 
    <entry1> 
    ... 
    </entry1> 
    <entry2> 
    ... 
    </entry2> 
</xml> 

我用XSD工具來生成模式,然後將C#類,顯然它創造:

public partial class entry1 
... 
public partial class entry2 

如何更改類,以便當我運行序列化/反序列化它會識別並將它們命名爲entry'n'在xml和我的對象?

我需要使用相同類型的無限項,並且更改xml是不可能的。

+0

有沒有有限數量的條目可能? –

+1

更改你的xml。 ' ... ...' –

+0

問題尚不清楚。你是否想將'entry1'和'entry2'類合併到一個單獨的類'entry'中,並使用這個單獨的類生成XML元素''和''?和/或你想支持任意數量的''元素嗎? –

回答

1

鑑於您無法更改XML,您將無法使用xsd.exe爲此XML生成類。 XmlSerializer沒有內置支持任意命名的元素,如<entry1>,<entry2>,... <entryN>。您可以在您的根類中實現IXmlSerializable,從而使XmlSerializer可以調用您的自定義(de)序列化代碼,也可以使用XmlDocument,XmlReader或(我的推薦)XDocument直接讀取XML,如果您認爲有必要,一個對象模型。

ASIDE:如果可能的話,推回這個API。這違反了良好的XML設計。 XML的本質是順序的。 XML閱讀<entry1/><entry2/>...<entryN/>應該只是<entry/><entry/>...<entry/>。 XML中的位置表示序列。

編輯:基於OP的評論,我會補充一點。如果你的XML真的很大,那麼執行一個字符串替換可能不是最好的解決方案。您可以創建一個XmlReader的子類,它將用<entry>元素替換<entryN>元素。您只需要覆蓋LocalName屬性。請注意,我在這裏並不是非常「安全」 - 任何以「entry」開頭的元素或屬性都將其名稱更改爲「entry」。我會留給你,以確定這對你是否足夠。如果沒有,那麼在替換名稱之前,確實有可能執行額外的狀態檢查(例如,確保你在一個元素上)。

// This class implements the LocalName override 
private class CustomXmlReader : CustomXmlReaderBase 
{ 
    // constructor 
    public CustomXmlReader(XmlReader inner) 
     : base(inner) 
    { 
    } 

    // LocalName override 
    public override string LocalName 
    { 
     get { return base.LocalName.StartsWith("entry") ? "entry" : base.LocalName; } 
    } 
} 

// This class implements base behavior for an XML reader that wraps another XML reader. 
private abstract class CustomXmlReaderBase : XmlReader 
{ 
    protected CustomXmlReaderBase(XmlReader inner) 
    { 
     _inner = inner; 
    } 

    private readonly XmlReader _inner; 

    public override string GetAttribute(string name) 
    { 
     return _inner.GetAttribute(name); 
    } 

    public override string GetAttribute(string name, string namespaceURI) 
    { 
     return _inner.GetAttribute(name, namespaceURI); 
    } 

    public override string GetAttribute(int i) 
    { 
     return _inner.GetAttribute(i); 
    } 

    public override bool MoveToAttribute(string name) 
    { 
     return _inner.MoveToAttribute(name); 
    } 

    public override bool MoveToAttribute(string name, string ns) 
    { 
     return _inner.MoveToAttribute(name, ns); 
    } 

    public override bool MoveToFirstAttribute() 
    { 
     return _inner.MoveToFirstAttribute(); 
    } 

    public override bool MoveToNextAttribute() 
    { 
     return _inner.MoveToNextAttribute(); 
    } 

    public override bool MoveToElement() 
    { 
     return _inner.MoveToElement(); 
    } 

    public override bool ReadAttributeValue() 
    { 
     return _inner.ReadAttributeValue(); 
    } 

    public override bool Read() 
    { 
     return _inner.Read(); 
    } 

    public override string LookupNamespace(string prefix) 
    { 
     return _inner.LookupNamespace(prefix); 
    } 

    public override void ResolveEntity() 
    { 
     _inner.ResolveEntity(); 
    } 

    public override XmlNodeType NodeType 
    { 
     get { return _inner.NodeType; } 
    } 

    public override string LocalName 
    { 
     get { return _inner.LocalName; } 
    } 

    public override string NamespaceURI 
    { 
     get { return _inner.NamespaceURI; } 
    } 

    public override string Prefix 
    { 
     get { return _inner.Prefix; } 
    } 

    public override string Value 
    { 
     get { return _inner.Value; } 
    } 

    public override int Depth 
    { 
     get { return _inner.Depth; } 
    } 

    public override string BaseURI 
    { 
     get { return _inner.BaseURI; } 
    } 

    public override bool IsEmptyElement 
    { 
     get { return _inner.IsEmptyElement; } 
    } 

    public override int AttributeCount 
    { 
     get { return _inner.AttributeCount; } 
    } 

    public override bool EOF 
    { 
     get { return _inner.EOF; } 
    } 

    public override ReadState ReadState 
    { 
     get { return _inner.ReadState; } 
    } 

    public override XmlNameTable NameTable 
    { 
     get { return _inner.NameTable; } 
    } 
} 
+0

謝謝。這正是我需要知道的。我認爲只需要一個類的'入口'並且在接收到xml替換所有出現的字符串「entry1」,「entry2」..通過「入口」,使用XmlSerializer來填充對象,然後在寫入xml後重復字符串replace。 這是一個非常大的XML,我絕對不想一個一個地構建它。非常感謝你的幫助! 是的,我確實同意這真的是一個非常糟糕的做法,這是我第一個想到的事情。 – Afonso

+0

增加了一些額外的評論。 –