#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]; }