2016-09-19 2 views
0

Я пишу код для сериализации некоторых данных модели вокселя. Код сериализатора отлично работает, за исключением того факта, что он вставляет 3 объявления xml, что вызывает ошибку при попытке де-сериализации.XmlSerializer, вставляющий 2 объявления xml

Мой код:

static Encoding encoding = new UTF8Encoding(false); 

public void Save(string path) { 
    /* trick to remove unessessarynamespace attributes */ 
    var ns = new XmlSerializerNamespaces(); 
    ns.Add("", ""); 

    var serializer = new XmlSerializer(typeof(VoxelData)); 

    var stream = new StreamWriter(path, false, encoding); 

    serializer.Serialize(stream, this, ns); // this refers to the VoxelData class 

    /* converts a dictionary to an array of a temporary serializable type */ 
    if (voxels != null) { 
     System.Type[] otherTypes = { typeof(Vector3Serializer) }; 
     var attrSerializer = new XmlSerializer(typeof(voxelsave[]), null, otherTypes, new XmlRootAttribute() { ElementName="voxels" }, ""); // new XmlRootAttribute() { ElementName = "attributes" },); 

     voxelsave[] voxelSave = voxels.Select(kv => new voxelsave() { data = kv.Value, position = new Vector3Serializer(kv.Key) }).ToArray(); 

     attrSerializer.Serialize(stream, voxelSave, ns); 
    } 
    /* converts a dictionary to an array of a temporary serializable type */ 
    if (attributes != null) { 
     System.Type[] otherTypes = { typeof(Vector3Serializer) }; 
     var attrSerializer = new XmlSerializer(typeof(attributesave[]), null, otherTypes, new XmlRootAttribute() { ElementName = "attributes" }, ""); // new XmlRootAttribute() { ElementName = "attributes" },); 

     attributesave[] attributeSave = attributes.Select(kv => new attributesave() { key = kv.Key, value = kv.Value }).ToArray(); 

     attrSerializer.Serialize(stream, attributeSave, ns); 
    } 
    stream.Close(); 
} 

Как и некоторые фрагменты классов сериализации:

[XmlType(TypeName = "attribute")] 
public class attributesave { 
    [XmlAttribute] 
    public object key; 

    public object value; 
} 

[XmlType(TypeName = "voxel")] 
public class voxelsave { 

    public Vector3Serializer position; 

    public Voxel data; 
} 

[System.Serializable] 
public class VoxelData { 

    [XmlIgnore] 
    private Dictionary<Vector3, Voxel> voxels = new Dictionary<Vector3, Voxel>(); 

    [XmlIgnore] 
    public Dictionary<object, object> attributes = new Dictionary<object, object>(); 

    [XmlAttribute("scale")] 
    public float scale = 1.0f; 

... 

} 

А вот пример вывода:

<?xml version="1.0" encoding="utf-8"?> 
<VoxelData scale="1" /> 
<?xml version="1.0" encoding="utf-8"?> 
<voxels> 
    <voxel> 
    <position x="0" y="0" z="0" /> 
    <data color="RGBA(1.000, 0.000, 0.000, 1.000)" scale="1" /> 
    </voxel> 
</voxels><?xml version="1.0" encoding="utf-8"?> 
<attributes> 
    <attribute key="handle"> 
    <value d3p1:type="vector3" x="0" y="0" z="0" xmlns:d3p1="http://www.w3.org/2001/XMLSchema-instance" /> 
    </attribute> 
</attributes> 

Как вы можете видеть, есть 3 xml? теги, 2 из которых не должно быть. Они вызывают ошибку при попытке десериализации, если я удаляю 2-й тег, они десериализуются в порядке.

Вопрос: почему этот второй тег вставлен и как его остановить?

+0

см. Это: http://stackoverflow.com/help/mcve Я бы хотел помочь, но мне нужно хотя бы минимальное количество кода, необходимого для воспроизведения вашей ошибки. В противном случае вам придется надеяться, что кто-то, кто видел эту конкретную проблему, прежде всего, может просто взглянуть на нее и сказать вам, что не так. – Jakotheshadows

+0

@Jakotheshadows Полный код - довольно огромный файл, который также использует серверные классы, поэтому было бы бесполезно публиковать сообщения. В любом случае, единственная релевантная часть кода на вопрос - это действительно функция сериализации. –

+0

Обычно это связано с объявлением элемента/класса XmlArray вместо XmlElement. XmlArray создает дополнительный уровень тегов. – jdweng

ответ

0

Как уже упоминалось в комментариях, задача, с которой вы сталкиваетесь, может быть исправлена ​​путем добавления дополнительных XmlWriterSettings к вашим двум дополнительным XML-сериализаторам.

Пример того, как это будет выглядеть бы:

var attrSerializer = new XmlSerializer(
      typeof(voxelsave[]) 
      , new XmlWriterSettings {OmitXmlDeclaration = true} 
      , ....) 

Рад, что помог !!

Смежные вопросы