2010-01-07 2 views
1

Я пишу элементы определенного типа в исходящий XML, используя IXmlSerializable. Я реализовал схему, и я пишу элементы. Следующий пример - пример.Поиск ссылок в IXmlSerializable

public void IXmlSerializable.WriteXml(XmlWriter writer) { 
    // Write Out Class. 
    foreach (var item in myItems) { 
    DataContractSerializer ds = new DataContractSerializer(typeof(MyType)); 
    ds.WriteObject(writer, item); 
    } 
} 

У меня есть проблема в том, что MyType объявлен с использованием ссылок

[DataContract(IsReference = true)] 
public class MyType { ... 

Таким образом, когда элемент уже был записан в XML он должен быть ссылкой.

Как узнать, была ли ссылка уже написана в xml? Я придерживаюсь мнения, что я должен просто игнорировать ссылки, которые я явно не контролирую. Таким образом, я буду составлять свой собственный идентификатор ссылки и ссылаться на свои собственные экземпляры.

Это явно плохой взломанный компромисс, поскольку я дублирую ссылки, которые не следует дублировать.

Есть ли способ узнать, что уже было написано, чтобы узнать, могу ли я найти идентификатор для уже сериализуемого элемента?

С уважением

Крейг.

ответ

0

Магия IsReference работает только для сериализации в рамках одного «эпизода». Эпизод - это один вызов WriteObject.

Допустим, вы должны были иметь объект верхнего уровня какого-либо типа верхнего уровня, как показано ниже:

[DC]  
class Container 
    { 
     [DM] 
     MyType i1 = new MyType(); 
     [DM] 
     MyType i2 = i1;; 
     [DM] 
     MyType i3 = i1; 
    } 

Теперь, если вы сериализовать экземпляр контейнера через вызов WriteObject, что когда «ids» и «refs» вступают в игру. Когда i1 становится сериализованным, он будет сериализован с идентификатором 1, но когда i2 и i3 будут сериализованы, каждый из них будет сериализован с атрибутами «REF», указывающими на идентификатор 1 MyType.

В вашем примере, поскольку каждый вызов WriteObject является отдельным эпизодом, каждый вызов сериализует весь граф объектов. Если вы не можете упаковать все ваши разные экземпляры MyType в объект более высокого уровня (или даже коллекцию), вам не повезло. Вот что вам нужно сделать - по сути, заставить все экземпляры MyType сериализоваться в одном вызове WriteObject более высокого уровня.