2013-11-28 2 views
7

Мой первый вопрос о SO:,) и это о XmlSerializer и пространства имен вопрос.XmlSerializer + Абстрактный класс + Производные классы = бесполезных пространств имен

Я знаю, что уже существует много вопросов о том, как удалить пространство имен Xml по умолчанию из корневого элемента Xml-файла, и это не предмет.

Вопрос: как удалить его из дочерних узлов при использовании производных классов?

Я создал свой собственный сериализатор, который может создавать собственные пространства имен или просто игнорировать их, и он хорошо работает для корневого элемента.

Но когда я использую абстрактный класс для перечисления некоторых производных классов внутри Список сериализации вставляет 2 атрибута внутри узлов каждого производного класса.

Как это:

<root> 
    <elements> 
    <element p3:type="XmlDerivedClass" xmlns:p3="{schema_url}" > 
    </element> 
    </elements> 
</root> 

Что касается моих классов:

// Root element 
[XmlRoot("root", Namespace="")] 
public class XmlRootElement 
{ 
    List<XmlBaseClass> _Elements; 
}  

// Base class 
[XmlInclude(typeof(XmlDerivedClass))] // Mandatory, prevents serialization errors 
[XmlRoot(Namespace="")] 
public abstract class XmlBaseClass 

// Derived class 
[XmlRoot("element", Namespace="")] 
public class XmlDerivedClass : XmlBaseClass 

Я пробовал некоторые общие решения:

  • Использование пространства имен = "" атрибут
  • , реализующее XmlNamespaceDeclarations свойства (с правом пустого пространства имен)
  • Перемещения XmlRoot() от базовой Clase производной один
  • Изменения XmlRoot() к XmlElement()

Постараюсь для добавления тега XmlInclude в список , чтобы узнать, не изменит ли он что-либо.

До сих пор ничего не получалось, чтобы удалить эти проклятые пространства имен ...

Если у кого есть решение для этого, я буду рад попробовать.

[EDIT 21/02/2014] Ну, похоже, что я единственный, кто столкнулся с этой проблемой. Я буду использовать простую строку . Замените, чтобы удалить бесполезный XML, но это довольно грязно.


PS: Для контекста, теги не являются проблемой для синтаксического анализа на другом конце, но они не нужны, так что я искал способ, чтобы удалить их.

PS2: Извините за любые орфографические ошибки, английский - это не мой родной язык.

+0

Я попытался добавить ** [XmlArrayItem («element», Type = typeof (XmlDerivedClass))], но он решил проблему только для одного производного класса. С несколькими производными классами с одним и тем же именем узла он не работает с этой системой. – Ethenyl

ответ

0

Если добавить [XmlType], вы можете дать сериализатору информации о типе, например, в пространстве имен она принадлежит:

// Base class 
[XmlInclude(typeof(XmlDerivedClass))] // Mandatory, prevents serialization errors 
[XmlType(Namespace="")] 
public abstract class XmlBaseClass 

// Derived class 
[XmlType("element", Namespace="")] 
public class XmlDerivedClass : XmlBaseClass 
+0

Спасибо за это, я попробую его как можно скорее. – Ethenyl

+0

Теперь я получаю смешные результаты ''. Я попытаюсь сыграть с ** XmlTypeAttribute **, чтобы узнать, могу ли я получить что-то лучшее. – Ethenyl

2

Я не уверен, является ли это решением, которое удовлетворяет ваши потребности, так это не очень приятно, но это работает, и это не кажется слишком грязным.

public abstract class Abs 
{ 
    public int Data { get; set; } 
} 


public class A : Abs{} 

public class B : Abs{} 

[Serializable] 
[XmlRoot(elementName: "name")] 
public class Ser 
{ 
    [XmlElement(elementName: "A")] 
    public List<A> AList { get; set; } 

    [XmlElement(elementName: "B")] 
    public List<B> BList { get; set; } 

    [XmlIgnore] 
    public List<Abs> AbsList { 
     get 
     { 
      var list = new List<Abs>(AList.ConvertAll(x=>(Abs)x)); 
      list.AddRange(BList.ConvertAll(x=>(Abs)x)); 
      return list; 
     } 
    } 
} 

Вместо XmlInclude вы можете создать список с объектами производного класса, а затем добавить их вместе или, может кэшировать их в частном члена. Обратите внимание, что это еще далеко от идеала, но оно работает для меня, поэтому я хотел бы поделиться им.

+0

В любом случае, если вы используете массив, вы можете использовать атрибуты ** XmlElement ** и ** XmlArrayItem ** для выполнения задания для вас. – user3194973

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