Xsd.exe Преобразование любого типа в XmlElement. Как заполнить сгенерированное свойство?

#c# #serialization #xsd.exe #any

#c# #сериализация #xsd.exe #Любой

Вопрос:

У меня есть XSD (это стандартный RFC xsd, определенный в http://web.rete.toscana.it/eCompliance/portale/dispatcher?from=rfcamp;pathname=/apps/tsf/data/eCompliance/eCRepository/rfc/0098.06/98.6.zip ) с помощью

 <complexType name="EventoClinico">
    ...
    <sequence>
...
        <element name="Corpo" type="sisrt:Corpo" minOccurs="0" />
    </sequence>
        ...
</complexType>
  

и «Corpo» — это

 <complexType name="Corpo">
    <sequence>
        <any namespace="##any" processContents="lax" />
    </sequence>
</complexType>
  

the xsd.exe инструмент преобразует элемент Corpo в

 public XmlElement Corpo;
  

свойство.

Вопрос в том:

Как я могу заполнить свойство своим пользовательским классом:

 public class Example{

public string AString {get;set;}
}
  

Как я могу установить EventoClinico.Corpo = новый пример(«строка»);?

С уважением.

Франческо.

Вот решение, предложенное в следующих сообщениях :

 public XmlElement Convert<TObj>(TObj obj) { 
        XmlSerializer s = new XmlSerializer(typeof(TObj)); 
        StringBuilder sb = new StringBuilder();
        XmlWriterSettings settings= new XmlWriterSettings();
        //settings.ConformanceLevel=ConformanceLevel.Fragment;
        settings.OmitXmlDeclaration=true;
        XmlWriter w = XmlWriter.Create(sb, settings);
        s.Serialize(w, obj); 
        return ToXmlElement(sb.ToString());
    }

    public XmlElement ToXmlElement(string xml)
    {
        XmlDocumentFragment frag = new XmlDocument().CreateDocumentFragment();
        frag.InnerXml = xml;
        return frag.FirstChild as XmlElement;
    }
  

Ответ №1:

Поскольку any не относится к строго определенному типу, xsd.exe генерирует для него XmlElement.

http://msdn.microsoft.com/en-us/library/2w8zbwa2 (v = против 80).aspx

Если вы хотите поместить туда значения, вам нужно будет использовать коллекции Attributes и childNodes.

Вы могли бы наследовать свой тестовый класс от XmlElement и использовать get и set его свойств, чтобы синхронизировать дочерние узлы и атрибуты с вашими данными участника.

 public class Example : XmlElement {

public string AString {
    get { return GetAttribute("astring"); }

    set { SetAttribute("astring", value); }
}

}
  

Комментарии:

1. Не могли бы вы привести мне пример того, о чем вы думаете? Похоже, что это правильный путь. С уважением.

2. Отметьте это как решение (маленькая галочка) — это позволит другим узнать, что решение работает, и побудит отвечающих обратить внимание на ваши вопросы.

3. Я думаю, мне нужен также общедоступный пример конструктора (string prefix, string localName, string namespaceURI, XmlDocument doc) :base(prefix, localName, namespaceURI, doc) { }

4. Звучит правильно. Меня не было рядом с машиной с компилятором C #, когда я писал этот пример.

Ответ №2:

Хм … кажется, что-то не так с вашей схемой, я думаю, type=»sisrt: Corpo» должно быть type =»Corpo» (потому что оно определено как <complexType name=»Corpo»>)?

Кроме того, если EventoClinico и Corpo определены в разных файлах .xsd, вам может потребоваться использовать директиву <xs:включить schemaLocation=»anotherfile.xsd» />

Комментарии:

1. Спасибо за ваш ответ, но это упрощение реального XSD (вы можете найти его по отредактированной ссылке), и XSD нельзя изменить, потому что это стандарт. Вопрос в том, как я могу передать объект в поле XmlElement?

2. Не уверен, может быть, вы могли бы попробовать что-то вроде: public XmlElement Convert<TObj>(TObj obj) { XmlSerializer s = new XmlSerializer(typeof(TObj)); StringBuilder sb = new StringBuilder(); XmlWriter w = XmlWriter.Create(sb); s.Serialize(w, obj); XmlDocument xe = new XmlDocument(); xe.ReadNode(XmlReader.Create(new StringReader(sb.ToString())); return (XmlElement)xe.ChildNodes[0]; }