node - Acoplar XML a la tabla HTML
xpath xml (5)
Debe haber una forma genérica de transformar algunos XML jerárquicos como, por ejemplo:
<element1 A="AValue" B="BValue">
<element2 C="DValue" D="CValue">
<element3 E="EValue1" F="FValue1"/>
<element3 E="EValue2" F="FValue2"/>
</element2>
...
</element1>
en el XML aplanado (html) recogiendo los atributos seleccionados a lo largo del camino y proporcionando diferentes etiquetas para los atributos que se convierten en encabezados de columna.
<table>
<tr>
<th>A_Label</th>
<th>D_Label</th>
<th>E_Label</th>
<th>F_Label</th>
</tr>
<tr>
<td>AValue</td>
<td>DValue</td>
<td>EValue1</td>
<td>FValue1</td>
</tr>
<tr>
<td>AValue</td>
<td>DValue</td>
<td>EValue2</td>
<td>FValue2</td>
</tr>
<table>
OK, entonces no hay una solución genérica debido a la nueva etiqueta de los atributos, pero entiendes lo que quiero decir con suerte. Empecé con todas las cosas de XSLT / XPATH, así que lo resolveré a tiempo, pero cualquier pista sería útil.
He utilizado una versión ampliada de la plantilla a continuación para aplanar XML estructurado. Advertencia: Hubo algún código específico de un caso en la versión original (de hecho convirtió el XML en CSV) que acabo de quitar y no probé esta versión.
La forma básica en que funciona debe ser clara: imprime todo lo que no tiene hijos de nodos y de lo contrario recurre a la plantilla en el nodo () que sí tiene hijos. No creo que maneje los atributos y comentarios correctamente como lo está ahora, pero eso no debería ser difícil de arreglar.
<?xml version="1.0" encoding="UTF-8"?>
<!-- XSL template to flatten structured XML, before converting to CSV. -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
<xsl:strip-space elements="*" />
<xsl:template match="/">
<xsl:apply-templates select="//yourElementsToFlatten"/>
</xsl:template>
<xsl:template match="//yourElementsToFlatten">
<xsl:apply-templates select="@*|node()"/>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:choose>
<!-- If the element has multiple childs, call this template
on its children to flatten it-->
<xsl:when test="count(child::*) > 0">
<xsl:apply-templates select="@*|node()"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:value-of select="text()" />
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
La pregunta original debe ser aclarada:
- ¿Qué sucede con BValue y CValue en la pregunta original? ¿Hay alguna razón por la cual no deberían ser parte de la estructura aplanada?
- ¿Todos los elementos del documento XML tienen 2 atributos o es completamente arbitrario?
- ¿Hay solo 3 tipos de elementos y siempre están anidados como se muestra en el ejemplo?
- ¿Puede su elemento1 repetirse o es este el elemento raíz de su documento?
En XSLT es posible escribir transformadores muy genéricos, pero a menudo es mucho más fácil escribir una hoja de estilos para transformar un documento cuando se pueden tener en cuenta las restricciones conocidas.
No estoy 100% seguro de lo que intenta hacer, pero esta solución puede funcionar si su elemento1, elemento2 y elemento3 están anidados de manera consistente.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<table>
<xsl:apply-templates select="//element3"></xsl:apply-templates>
</table>
</xsl:template>
<xsl:template match="element3">
<tr>
<td><xsl:value-of select="../../@A"/></td>
<td><xsl:value-of select="../../@B"/></td>
<td><xsl:value-of select="../@C"/></td>
<td><xsl:value-of select="../@D"/></td>
<td><xsl:value-of select="@E"/></td>
<td><xsl:value-of select="@F"/></td>
</tr>
<xsl:apply-templates select="*"></xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>
Ya tenemos un programa Pro * C leyendo desde una base de datos Oracle, llama a un script perl que a su vez ejecuta algo de Java para extraer datos en formato XML de la base de datos antes mencionada para llamar a un archivo por lotes para ejecutar vbscript FTPing el archivo a otro servidor. Realmente estaba esperando algo en Fortran.
Necesitaba un XSLT similar pero con una profundidad desconocida, aquí es cómo lo hice.
Primero, agregue un contenedor para la tabla HTML resultante / lista def y llame a la plantilla mode = "puke" para aplanar nuestro árbol XML:
<xsl:element name="div">
<xsl:attribute name="class" select="puke" />
<xsl:apply-templates select="$notice" mode="puke" />
</xsl:element>
Aquí hacemos coincidir cada nodo para mostrar su contenido (por ejemplo, texto ()) y sus atributos. Hacemos esto recursivamente Usé dl / dt / dd porque mi árbol fuente era un árbol complejo que no se puede aplanar como a.
<!-- @description:
Display all field from the notice so the customer can tell what he want
-->
<xsl:template match="node()" mode="puke">
<xsl:message>
puking : <xsl:value-of select="local-name( . )" />
</xsl:message>
<xsl:element name="dl">
<xsl:element name="dt">
<xsl:attribute name="class">tagName</xsl:attribute>
<xsl:value-of select="local-name( . )" />
</xsl:element>
<xsl:element name="dd">
<xsl:attribute name="class">tagText</xsl:attribute>
<xsl:value-of select="text()" /></xsl:element>
<xsl:element name="dl">
<xsl:attribute name="class">attr</xsl:attribute>
<!-- display attribute -->
<xsl:apply-templates select="@*" />
</xsl:element>
</xsl:element>
<!-- recursive call on node() -->
<xsl:apply-templates select="./*" mode="puke" />
</xsl:template>
Relacionar el atributo de un nodo dado y mostrarlos.
El uso de CSS para formatear el HTML resultante:
<style>
.puke {
background-color: #BDD6DE;
clear: both;
}
.tagName, .attrName {
float: left;
}
.tagText, .attrText {
clear: right;
}
</style>