¿Por qué mi XSL no encuentra nada para procesar en este XML?

¿Por qué mi XSL no encuentra nada para procesar en este XML? Estoy tratando de convertir la salida del informe cognos xml en otra forma (sí, sé que cognos produce html, pero necesito algo más). Simplemente produce la palabra "Título:" y se detiene.

Aquí está mi XSL:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://developer.cognos.com/schemas/xmldata/1/" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">

    <xsl:template match="/">

    <xsl:template match="rows">
        <xsl:apply-templates select="rowEdge"/>
    </xsl:template>

    <xsl:template match="rowEdge">
        <b>Caption:</b> <xsl:value-of select="caption"/><br/>
        <xsl:if test="@id">
            <b>id:</b> <xsl:value-of select="@id"/><br/>
        </xsl:if>
        <xsl:if test="rowEdge">
            <xsl:apply-templates select="rowEdge"/>
        </xsl:if>
    </xsl:template>

    <html>
        <head><title>%s</title></head>
        <body>
            <xsl:apply-templates select="dataset/crosstab/rows"/>
        </body>
    </html>

    </xsl:template>
</xsl:stylesheet> 

Aquí está el XML (tuve que eliminar algunos, pero debería dar una idea):

<?xml version="1.0" encoding="utf-8" ?> 
 <dataset xmlns="http://developer.cognos.com/schemas/xmldata/1/" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">
 <crosstab>
 <values>
  <value row="R1" col="C1" xs:nil="true" /> 
  <value row="R1" col="C2" xs:nil="true" /> 
  <value row="R1" col="C3" xs:nil="true" /> 
  <value row="R1" col="C4" xs:nil="true" /> 
  <value row="R1" col="C5" xs:nil="true" /> 
  <value row="R1" col="C6" xs:nil="true" /> 
  <value row="R1" col="C7" xs:nil="true" /> 
  <value row="R1" col="C8" xs:nil="true" /> 
  <value row="R1" col="C9" xs:nil="true" /> 
  <value row="R2" col="C1">0</value> 
  <value row="R2" col="C2">12.61728395</value> 
  <value row="R2" col="C3">1320.40677966</value> 
  <value row="R2" col="C4">7</value> 
  <value row="R2" col="C5">1.90318499</value> 
  <value row="R2" col="C6">108.66456135</value> 
  <value row="R2" col="C7">776.61407946</value> 
  <value row="R2" col="C8">-0.86007907</value> 
  <value row="R2" col="C9">46.53571429</value> 
</values>
 <corner>
  <caption>Time Period: DCG Incurred Paid Year</caption> 
  </corner>
 <columns>
 <colEdge>
  <caption>Jan 02 to Dec 02 {All Data} CRxIp</caption> 
 <colEdge>
  <caption>2002</caption> 
 <colEdge id="C1">
  <caption>Member Age Avg</caption> 
  </colEdge>
 <colEdge id="C2">
  <caption>Days Supply Per Script Rx</caption> 
  </colEdge>
 <colEdge id="C3">
  <caption>Net Pay Per Pat Med</caption> 
  </colEdge>
 <colEdge id="C4">
  <caption>Days LOS Admit Acute</caption> 
  </colEdge>
 <colEdge id="C5">
  <caption>Days LOS Admit Acute</caption> 
  </colEdge>
 <colEdge id="C6">
  <caption>Allow Amt PMPM Med and Rx {Cmpl}</caption> 
  </colEdge>
 <colEdge id="C7">
  <caption>Allow Amt PMPM Med and Rx {Cmpl}</caption> 
  </colEdge>
 <colEdge id="C8">
  <caption>% Diff Allow Amt PMPM Med and Rx {Cmpl}</caption> 
  </colEdge>
 <colEdge id="C9">
  <caption>Relative Risk Score Prosp Explan NonRescaled</caption> 
  </colEdge>
  </colEdge>
  </colEdge>
  </columns>
 <rows>
 <rowEdge>
  <caption>Subsets</caption> 
 <rowEdge>
  <caption>Plan Type Medstat</caption> 
 <rowEdge id="R1">
  <caption>Cohort Medstat</caption> 
  </rowEdge>
  </rowEdge>
  </rowEdge>
 <rowEdge>
  <caption>Chronic Episodes</caption> 
 <rowEdge>
  <caption>HMO (Managed Care)</caption> 
 <rowEdge id="R2">
  <caption>Females, Ages &lt; 1</caption> 
  </rowEdge>
</rowEdge>
 </rowEdge>
 </rows>
  </crosstab>
  </dataset>

preguntado el 22 de mayo de 12 a las 18:05

Parece que su plantilla raíz está un poco desordenada: ¿debería la parte html en la parte inferior ir a la primera plantilla? -

1 Respuestas

En XSLT 1.0 (que está utilizando), los espacios de nombres predeterminados no se tienen en cuenta en las expresiones XPath.

Lo que tienes que hacer es:

1) Asigne un prefijo al espacio de nombres predeterminado de su documento de instancia en su transformación XSLT, por ejemplo:

 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="cog:http://developer.cognos.com/schemas/xmldata/1/" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">

2) Use este prefijo antes de cada nombre de elemento (pero no antes de los nombres de atributos) en sus expresiones XPath:

<xsl:template match="cog:rowEdge">
    <b>Caption:</b> <xsl:value-of select="cog:caption"/><br/>
    <xsl:if test="@id">
       <b>id:</b> <xsl:value-of select="@id"/><br/>
    </xsl:if>
    <xsl:if test="cog:rowEdge">
        <xsl:apply-templates select="cog:rowEdge"/>
    </xsl:if>
</xsl:template>

Nota: no necesita probar que hay un cog:rowEdge antes de aplicar las plantillas: las plantillas de aplicación no harán nada si no hay nodos en su atributo de selección de todos modos;) ...

Hay un par de otros errores en la hoja de estilo:

  1. Las plantillas no se pueden incrustar
  2. Debe haber un atributo de versión en el xsl:stylesheet elemento.

La hoja de estilo correcta sería:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:cog="http://developer.cognos.com/schemas/xmldata/1/" version="1.0">

    <xsl:template match="/">

        <html>
            <head>
                <title>%s</title>
            </head>
            <body>
                <xsl:apply-templates select="cog:dataset/cog:crosstab/cog:rows"/>
            </body>
        </html>

    </xsl:template>

    <xsl:template match="cog:rows">
        <xsl:apply-templates select="cog:rowEdge"/>
    </xsl:template>

    <xsl:template match="cog:rowEdge">
        <b>Caption:</b>
        <xsl:value-of select="cog:caption"/>
        <br/>
        <xsl:if test="@id">
            <b>id:</b>
            <xsl:value-of select="@id"/>
            <br/>
        </xsl:if>
        <xsl:apply-templates select="cog:rowEdge"/>
    </xsl:template>

</xsl:stylesheet>

contestado el 22 de mayo de 12 a las 19:05

Gracias. También tuve que invocarlo de esta manera: - lkohl

La recursividad no funciona, simplemente imprime el texto completo (principal + secundario) de ese primer borde de fila y se cierra. - lkohl

Bueno, me había centrado en el problema del espacio de nombres que es muy común, pero al mirar su XSLT, veo que hay otro problema: ¡no puede incrustar plantillas dentro de plantillas como lo está haciendo! Para solucionarlo, debe mover las plantillas incrustadas fuera de la del nodo raíz (/) y agregar el prefijo antes de todos los nombres de elementos en todas las expresiones XPath. - Eric van der Vlist

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.