2012-07-02 2 views
12

Ho il problema:Serializzare XML stesso tag due volte

Devo serializzare la classe sul file XML. Ma due proprietà devono essere nominati con lo stesso nome:

xml desiderata:

<?xml version="1.0"?> 
<Test> 
    <HeaderText> 
    <Tag1>AAA</Tag1> 
    </HeaderText> 
    <HeaderText> 
    <Tag2>BBB</Tag2> 
    </HeaderText> 
</Test> 

Non ho bisogno di deserializzare nuovamente di opporsi.

Codice:

public class Header1 
{ 
    [XmlElement("Tag1")] 
    public String Tag1 { get; set; } 
} 

public class Header2 
{ 
    [XmlElement("Tag2")] 
    public String Tag2 { get; set; } 
} 

public class Test 
{ 
    [XmlElement("HeaderText")] 
    public Header1 Header1 { get; set; } 

    [XmlElement("HeaderText")] 
    public Header2 Header2 { get; set; } 
} 

var doc = new Test 
{ 
    Header1 = new Header1 { Tag1 = "AAA" }, 
    Header2 = new Header2 { Tag2 = "BBB" } 
}; 

var xml = new XmlSerializer(typeof(Test)); 
using (var fs = new FileStream("test.xml", FileMode.Create)) 
{ 
    xml.Serialize(fs, doc); 
} 

Questo codice non funziona.

L'elemento XML 'HeaderText' dal namespace '' è già presente nell'ambito corrente. Utilizzare gli attributi XML per specificare un altro nome o spazio dei nomi XML per l'elemento.

Cosa posso fare?

esempio reale:

<Product> 
    <RecordReference>1-15991</RecordReference> 
    <MainSubject> 
     <MainSubjectSchemeIdentifier>66</MainSubjectSchemeIdentifier> 
     <SubjectCode>2</SubjectCode> 
    </MainSubject> 
    <MainSubject> 
     <MainSubjectSchemeIdentifier>20</MainSubjectSchemeIdentifier> 
     <SubjectHeadingText>Venäläisiä kirjoja: uskonto, teosofia, mystiikka</SubjectHeadingText> 
    </MainSubject> 
</Product> 

risposta

9

usare un array:

public class Test 
{ 
    [XmlElement("HeaderText")] 
    public string[] HeaderText { get; set; } 
} 

e poi:

var doc = new Test 
{ 
    HeaderText = new[] { "AAA", "BBB" } 
}; 
var xml = new XmlSerializer(typeof(Test)); 
using (var fs = new FileStream("test.xml", FileMode.Create)) 
{ 
    xml.Serialize(fs, doc); 
} 

funziona anche con List<string>.


UPDATE:

Con oggetti complessi si definisce un modello:

public class Header 
{ 
    public string Tag { get; set; } 
} 

e poi si dispone di una collezione di questo modello:

public class Test 
{ 
    [XmlElement("HeaderText")] 
    public Header[] HeaderText { get; set; } 
} 

e poi si serializzare:

var doc = new Test 
{ 
    HeaderText = new[] 
    { 
     new Header { Tag = "AAA" }, 
     new Header { Tag = "BBB" } 
    } 
}; 
var xml = new XmlSerializer(typeof(Test)); 
using (var fs = new FileStream("test.xml", FileMode.Create)) 
{ 
    xml.Serialize(fs, doc); 
} 
+0

Funziona anche con 'Lista pubblico HeaderText {} ', più facile da Aggiungi/Rimuovi articoli. – Tisho

+0

@Tisho, yeap, ho aggiornato la mia risposta per includere queste informazioni. –

+0

Grazie, funziona per proprietà semplici. Si prega di consultare il codice aggiornato in questione. – Lari13

8

Si potrebbe dire il serializzatore di ignorare le proprietà attuali e aggiungere uno nuovo con lo scopo di serializzazione:

public class Test 
{ 
    [XmlIgnore] 
    public String Header1 { get; set; } 

    [XmlIgnore] 
    public String Header2 { get; set; } 

    [XmlElement("HeaderText")] 
    public String[] HeaderText 
    { 
     get{ return new[]{Header1,Header2}; } 
     set{ if(value.Length == 2) { Header1 = value[0]; Header2 = value[1];} } 
    } 
} 

vivo esempio: http://rextester.com/YVEF64085