2011-02-11 10 views
7

Tengo el siguiente tipo complejo en mi esquema XML:Cómo utilizar tipos complejos con xs: any/## cualquiera y mixto en el código generado por la herramienta XSD

<xs:complexType name="Widget" mixed="true"> 
    <xs:sequence> 
     <xs:any namespace="##any" processContents="skip" minOccurs="0" maxOccurs="unbounded"/> 
    </xs:sequence> 
</xs:complexType> 

El elemento en XML derivado podría contener cadena o podría contener XML bien formado, por lo tanto, el atributo mixto es verdadero.

Cuando ejecuto esto a través de la herramienta XSD .NET me sale el siguiente código generará:

public partial class Widget{ 

    private System.Xml.XmlNode[] anyField; 

    /// <remarks/> 
    [System.Xml.Serialization.XmlTextAttribute()] 
    [System.Xml.Serialization.XmlAnyElementAttribute()] 
    public System.Xml.XmlNode[] Any { 
     get { 
      return this.anyField; 
     } 
     set { 
      this.anyField = value; 
     } 
    } 
} 

La pregunta que tengo es que no estoy del todo seguro de cómo entonces debería usar este. En última instancia lo que necesito para ser capaz de establecer el valor del widget a cualquiera:

<widget>Hello World!</widget> 

o

<widget> 
    <foo>Hello World</foo> 
</widget> 

Ambos de los cuales validar agaisnt el esquema

Respuesta

2

Para ello:

<widget> 
    <foo>Hello World</foo> 
</widget> 

Utilice esta:

XmlDocument dom = new XmlDocument(); 
Widget xmlWidget = new Widget(); 
xmlWidget.Any = new XmlNode[1]; 
xmlWidget.Any[0] = dom.CreateNode(XmlNodeType.Element, "foo", dom.NamespaceURI); 
xmlWidget.Any[0].InnerText = "Hello World!"; 

Para esto:

<widget>Hello World!</widget> 

Utilice esta:

XmlDocument dom = new XmlDocument(); 
XmlNode node = dom.CreateNode(XmlNodeType.Element, "foo", dom.NamespaceURI); 
node.InnerText = "Hello World"; 

Widget w = new Widget(); 
w.Any = new XmlNode[1]; 
w.Any[0] = node.FirstChild; 
+0

Eso no funcionará, no has inicializado xmlWidget.Any [0]. Entonces arrojaría una excepción de referencia nula. – MrEyes

+0

Actualicé mi respuesta para tratar las NullReferenceExceptions. Sin embargo, no estoy seguro de que pueda cumplir la opción de "solo texto interno". hacer esto en el código significaría que la clase Widget podría funcionar como un tipo de cadena, así como una matriz de Nodos. No creo que esto sea posible con la generación estándar de XSD. – pmartin

+0

Hice una edición que es bastante similar al código que publicaste. No estoy seguro de que vas a encontrar una forma diferente de hacer esto. Realmente, intentas anular la propiedad del widget. En una instancia, desea que sea solo una cadena y en otras instancias desea una matriz de nodos, pero no puede definir una propiedad del mismo nombre varias veces en una sola clase. – pmartin

0

publicar esto como una respuesta técnicamente funciona y responde la pregunta. Sin embargo, parece un truco realmente desagradable. Entonces, si alguien tiene una solución alternativa y mejor, soy todo oídos.

string mystring= "if I check this code in it will at least have comedy value"; 

XmlDocument thisLooksBad = new XmlDocument(); 
thisLooksBad.LoadXml("<temp>" + mystring + "</temp>"); 

Widget stringWidget = new Widget(); 
stringWidget.Any = new XmlNode[1]; 
stringWidget.Any[0] = thisLooksBad.SelectSingleNode("/temp").FirstChild; 

Como se puede ver que estoy poniendo mi cadena en un XmlDocument envuelto en etiquetas, esto funciona, compila y serializa y sin problemas - por lo que sí que es una solución, pero me parece que este es un corte desagradable.

string myxml = "<x><y>something</y></x>"; 

XmlDocument thisDoesntLookSoBad = new XmlDocument(); 
thisLooksBad.LoadXml(myxml); 

Widget xmlWidget = new Widget(); 
xmlWidget.Any = new XmlNode[1]; 
xmlWidget.Any[0] = thisDoesntLookSoBad; 

En este ejemplo estoy poniendo mi XML en un XmlDocument y luego asignar a que la clase generada. Esto tiene más sentido ya que estoy trabajando con cadenas XML no en bruto.

Curiosamente también puedo hacer esto y funciona así (pero también es un corte desagradable):

string myxml = "<x><y>something</y></x>"; 

XmlDocument dom = new XmlDocument(); 
dom.LoadXml("<temp>" + myxml + "</temp>"); 

Widget xmlWidget = new Widget(); 
xmlWidget.Any = new XmlNode[1]; 
xmlWidget.Any[0] = dom.SelectSingleNode("/temp").FirstChild; 
+0

¿Cuál de estos ejemplos satifies el ' Hello World! 'requisito. – pmartin

+0

La primera muestra se deserializa a: si compruebo este código, al menos tendrá valor de comedia MrEyes

+0

Como usted dice, esto hace el trabajo, pero yo permito la solución de Pmartin porque es más robusta, es decir, no usa concatenación de cadenas para construir el Xml DOM. –

Cuestiones relacionadas