2012-08-02 23 views
5

Im trabajando para automatizar la prueba de una API que toma y devuelve XML, por lo que quiero traducir los datos de retorno documentados de la API en el esquema tanto como sea posible. Elegí RelaxNG para esta tarea en función de la facilidad de uso y el aprendizaje.¿Puede relajar especificar un conjunto desordenado de elementos con el mismo nombre, pero con diferentes atributos?

Antes me tiro en toda la info, aquí está la pregunta: ¿

¿Es posible describir "conjunto no ordenado de elementos, con el mismo nombre pero diferentes atributos"?

Aquí es un objeto de muestra de lo que estoy teniendo problemas para describirlos:

<item> 
    <id>d395136e-d060-4a6e-887c-c0337dd7ad09</id> 
    <name>The item has a name</name> 
    <link rel="self" type="type1" href="url" /> 
    <link rel="download" type="type2" href="url" /> 
    <link rel="relatedData" type="type3" href="url" /> 
</item> 

Los objetos de enlace son la parte que me estoy colgó. Aquí está el problema:

  • El orden de los elementos en el interior artículo no está garantizado, por lo que estoy tratando de poner todos los elementos en <interleave> estructura.
  • Habrá múltiples elementos <link> dentro de <item>, con diferentes conjuntos de atributos (es decir, <item> DEBE tener un enlace 'propio', un enlace 'descargar' y un enlace 'relatedData' para ser válido).
  • Se requiere uno de cada tipo de enlace, pero nuevamente no se garantiza el orden.

Me trataron de describir el esquema de este modo:

<element name="item"> 
    <interleave> 
     <element name="id"><text/></element> 
     <element name="name"><text/></element> 
     <ref name="selfLink"/> 
     <ref name="launchLink"/> 
     <ref name="thumbnailLink"/> 
    </interleave> 
</element> 

las referencias 'enlace' se definen en otro lugar de este modo:

<define name="selfLink"> 
<element name="link"> 
    <attribute name="href"><text/></attribute> 
    <attribute name="rel"><value>self</value></attribute> 
    <attribute name="type"><value>type1</value></attribute> 
</element> 
</define> 

El analizador no está satisfecho sobre esto - de Jing Obtengo error: the element "link" can occur in more than one operand of "interleave". Puedo ver lo que está pasando, pero esperaba poder manejar la idea de 'elementos con el mismo nombre pero diferentes atributos' como elementos únicos.

Al mover los enlaces de referencia de intercalación lo analiza, pero estaré esperando que el validador explote cada vez que el pedido cambie en los datos devueltos.

¿Alguna idea, o es esto imposible? ¿Existe un problema inherente con el XML que estoy procesando que me obligue a mover parte de esto a una lógica de procesamiento más alta en mi aplicación de prueba (compruebe manualmente cada tipo de enlace después de ejecutar una validación XML más genérica?)

+0

Cuando se dice "diferentes atributos", es lo que realmente quiere decir "diferentes valores de los atributos"? – mzjn

+0

En realidad, sí, gracias por la aclaración. El mismo conjunto de atributos con diferentes requisitos de valor. – James

Respuesta

3

parece que se han topado con un restriction on interleave en RELAX NG. Intentaré hacer esto en Schematron, o quizás una combinación de RELAX NG y Schematron.

Aquí hay un fragmento que comprueba sus <link> elementos utilizando la versión de Schematron que es supported by Jing:

<schema xmlns="http://www.ascc.net/xml/schematron"> 
    <pattern name="link pattern"> 
    <rule context="item"> 
     <assert test='count(link) = 3'>There must be 3 link elements.</assert> 
     <assert test="count(link[@rel = 'self' and @type ='type1']) = 1">There must be 1 link element wwhere @rel='self' and @type='type1'.</assert> 
     <assert test="count(link[@rel = 'download' and @type ='type2']) = 1">There must be 1 link element where @rel='download' and @type='type2'.</assert> 
     <assert test="count(link[@rel = 'relatedData' and @type = 'type3']) = 1">There must be 1 link element where @rel='relatedData' and @type='type3'.</assert> 
    </rule> 
    </pattern> 
</schema> 
+1

Esto capta la idea, y pude implementarlo para este ejemplo y confirmar que funciona. Habiendo metido los dedos de los pies en la incrustación de schematron en RelaxNG, creo que esta podría ser la manera de hacerlo por ahora hasta/a menos que encuentre una barricada. Obtengo la capacidad de mantener la validación xml en un solo lugar (no dividido entre un validador y la lógica de la aplicación) a expensas de la necesidad de configurar un pipeline de configuración/procesamiento más complejo. Parece una compensación razonable. – James

1

a ver si el siguiente esquema ayuda a

<grammar xmlns="http://relaxng.org/ns/structure/1.0"> 
<start> 
    <element name="item"> 
     <interleave> 
      <element name="id"><text/> 
      </element> 
      <element name="name"><text/></element> 
      <oneOrMore> 
       <ref name="link"/> 
      </oneOrMore> 
     </interleave> 
    </element> 
</start> 

<define name="link"> 
    <element name="link"> 
     <attribute name="href"/> 
     <choice> 
      <group> 
       <attribute name="rel"><value>self</value></attribute> 
       <attribute name="type"><value>type1</value></attribute> 
      </group> 
      <group> 
       <attribute name="rel"><value>download</value></attribute> 
       <attribute name="type"><value>type2</value></attribute> 
      </group> 
      <group> 
       <attribute name="rel"><value>relatedData</value></attribute> 
       <attribute name="type"><value>type3</value></attribute> 
      </group> 
     </choice> 
    </element> 
</define> 
</grammar> 
+0

Si bien esto no me lleva a una verificación válida garantizada de mis datos, esta idea me acerca: al poner un '' en mi intercalación con el 'vínculo' de X, puedo hacer coincidir 'X objetos de enlace que pueden agruparse en algún lugar en el elemento ', y al usar su idea' choice 'en el esquema de 'link', puedo validar que todos los' link's encontrados provienen de un conjunto de elementos de enlace válidos. El código de la aplicación de nivel superior todavía tendrá que verificar que los 3 enlaces recibidos sean los tres reales que se esperan en el objeto devuelto ("obtuve un enlace de descarga, un enlace propio y un enlace relacionadoData en el' elemento' "). Gracias. – James

Cuestiones relacionadas