2012-08-24 7 views
5

En este ejemplo de código tengo 2 desafíos uno es establecer el nodo B1 después del nodo B y antes del nodo C, D y E y el segundo desafío es Agregue el segundo nodo KEY a la estructura/ROOT/E/OTHER/DEAL/KEYS.Cómo aplicar varias definiciones de plantilla donde cada una de ellas está cambiando la misma estructura XML

Este XML de ejemplo:

 <ROOT> 
      <A>some A text</A> 
      <B>some B text</B> 
      <C>some C text</C> 
      <D>some D text</D> 
      <E> 
      <OTHER> 
       <DEAL> 
       <KEYS> 
        <KEY> 
        <KeyIdentifierType>KeyIdentifierTypeA</KeyIdentifierType> 
        <KeyValue>123456|1</KeyValue> 
        </KEY> 
       </KEYS> 
       </DEAL> 
      </OTHER> 
      </E> 
     </ROOT> 

después de la transformación:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
     <xsl:strip-space elements="*"/> 
     <xsl:output method="xml" indent="yes"/> 

     <xsl:template match="@*|node()"> 
      <xsl:copy> 
       <xsl:apply-templates select="@*|node()"/> 
      </xsl:copy> 
     </xsl:template> 

     <!-- Identifiers are added by the system. Need to pass parms from the calling program --> 
     <xsl:template match="ROOT" name="add-B1"> 
      <xsl:variable name="elements-after" select="C|D|E"/> 
      <xsl:copy> 
       <xsl:copy-of select="* except $elements-after"/> 
       <B1>some B1 text</B1> 
       <xsl:copy-of select="$elements-after"/> 
      </xsl:copy> 
     </xsl:template> 

     <!-- KEY is added by the system. Need to pass parms from the calling program --> 
     <xsl:template match="ROOT/E/OTHER/DEAL/KEYS" name="add-KEYS"> 
      <xsl:param name="KeyIdentifierTypeB">654321|1</xsl:param> 
      <xsl:copy> 
       <xsl:copy-of select="*"/> 
       <KEY> 
        <KeyIdentifierType>KeyIdentifierTypeB</KeyIdentifierType> 
        <KeyValue> 
         <xsl:value-of select="$KeyIdentifierTypeB"/> 
        </KeyValue> 
       </KEY> 
      </xsl:copy> 
     </xsl:template> 
    </xsl:stylesheet> 

se convierten en:

 <?xml version="1.0" encoding="UTF-8"?> 
     <ROOT> 
      <A>some A text</A> 
      <B>some B text</B> 
      <B1 xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">some B1 text</B1> 
      <C>some C text</C> 
      <D>some D text</D> 
      <E> 
       <OTHER> 
        <DEAL> 
         <KEYS> 
          <KEY> 
           <KeyIdentifierType>KeyIdentifierTypeA</KeyIdentifierType> 
           <KeyValue>123456|1</KeyValue> 
          </KEY> 
         </KEYS> 
        </DEAL> 
       </OTHER> 
      </E> 
     </ROOT> 

razón por la segunda definición de plantilla ha sido completamente ignorado?

Se resolvió el primer código de la universidad B1 se establece después del nodo B y antes del nodo C, D y E o en otras palabras se establece el nodo B1 y los nodos que deben estar detrás de él son: C, D y E
La segunda coincidencia de plantilla = "ROOT/E/OTHER/DEAL/KEYS" que debería satisfacer la segunda parte de desafío: Agregar el segundo nodo KEY a la estructura/ROOT/E/OTHER/DEAL/KEYS, se ha ignorado completamente. Además de este hecho, si comenta la primera coincidencia de plantilla sobre el nodo ROOT, la segunda plantilla match = "ROOT/E/OTHER/DEAL/KEYS" funcionará correctamente, realmente agregará la clave adicional, pero yo no No sé por qué la primera coincidencia de plantilla siempre anula la segunda. Intento el xsl: template match = "ROOT/E/OTHER/DEAL/KEYS ... y el xsl: for-each select = ... y xsl: call-template name =" add-KEYS "pero nada me ayudó

Realmente entiendo que aplicar plantillas, unir plantillas de nodos con una estructura más alta con la más alta prioridad Cambiar el lugar de la plantilla en el archivo XSLT no tendrá ningún impacto, no lo leerá en la secuencia de línea exacta, en su lugar lo procesará al hacer coincidir la prioridad. "aplicar-plantillas" para cada plantilla coincidente hará un cambio en la estructura XML, implícitamente hará el "por-cada" para nosotros, pero yo no sé cómo "asesorar" la segunda plantilla que ha cambiado la estructura, y por qué debería hacerlo, porque la segunda coincidencia de la plantilla busca una ubicación diferente de XPath, que btw nunca ha sido tocado desde la primera plantilla. ¿Debo aplicar la secuencia de la plantilla? g en mi caso? ... y ¿cuál es la mejor práctica de cómo hacerlo?

Resultado esperado:

 <?xml version="1.0" encoding="UTF-8"?> 
     <ROOT> 
      <A>some A text</A> 
      <B>some B text</B> 
      <B1>some B1 text</B1> 
      <C>some C text</C> 
      <D>some D text</D> 
      <E> 
       <OTHER> 
        <DEAL> 
         <KEYS> 
          <KEY> 
           <KeyIdentifierType>KeyIdentifierTypeA</KeyIdentifierType> 
           <KeyValue>123456|1</KeyValue> 
          </KEY> 
          <KEY> 
           <KeyIdentifierType>KeyIdentifierTypeB</KeyIdentifierType> 
           <KeyValue>654321|1</KeyValue> 
          </KEY> 
         </KEYS> 
        </DEAL> 
       </OTHER> 
      </E> 
     </ROOT> 

Respuesta

3

La segunda plantilla match="ROOT/E/OTHER/DEAL/KEYS" que deben satisfacer la segunda parte reto: Añadir el segundo nodo clave de la estructura /ROOT/E/OTHER/DEAL/KEYS, se ha ignorado por completo.

El problema es que en la plantilla que coincide con ROOT no hay ningún xsl:apply-templates. Una plantilla solo se selecciona para la ejecución en el resultado de una instrucción xsl:apply-templates. En su código no hay ningún xsl:apply-templates, por lo tanto, el procesador XSLT ya no aplica plantillas y finaliza la ejecución.

Sería diferente si reemplazó xsl:copy-of con xsl:apply-templates.

Aquí es cómo hacer esto:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="/*"> 
    <xsl:copy> 
    <xsl:apply-templates select="@*|B/preceding-sibling::node()"/> 
    <xsl:apply-templates select="B"/> 
    <B1>some B1 text</B1> 
    <xsl:apply-templates select="B/following-sibling::node()"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="KEY"> 
    <xsl:copy> 
    <xsl:apply-templates select="@*|node()"/> 
    <KEY> 
    <KeyIdentifierType>KeyIdentifierTypeB</KeyIdentifierType> 
    <KeyValue> 
    <xsl:value-of select="'654321|1'"/> 
    </KeyValue> 
    </KEY> 
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 

Cuando se aplica esta transformación en el documento XML proporcionado:

<ROOT> 
    <A>some A text</A> 
    <B>some B text</B> 
    <C>some C text</C> 
    <D>some D text</D> 
    <E> 
     <OTHER> 
      <DEAL> 
       <KEYS> 
        <KEY> 
         <KeyIdentifierType>KeyIdentifierTypeA</KeyIdentifierType> 
         <KeyValue>123456|1</KeyValue> 
        </KEY> 
       </KEYS> 
      </DEAL> 
     </OTHER> 
    </E> 
</ROOT> 

el resultado deseado, correcta se produce:

<ROOT> 
    <A>some A text</A> 
    <B>some B text</B> 
    <B1>some B1 text</B1> 
    <C>some C text</C> 
    <D>some D text</D> 
    <E> 
     <OTHER> 
     <DEAL> 
      <KEYS> 
       <KEY> 
        <KeyIdentifierType>KeyIdentifierTypeA</KeyIdentifierType> 
        <KeyValue>123456|1</KeyValue> 
        <KEY> 
        <KeyIdentifierType>KeyIdentifierTypeB</KeyIdentifierType> 
        <KeyValue>654321|1</KeyValue> 
        </KEY> 
       </KEY> 
      </KEYS> 
     </DEAL> 
     </OTHER> 
    </E> 
</ROOT> 
+0

¡Muchas gracias! –

+0

@ user1619586, eres bienvenido. –

Cuestiones relacionadas