Pregunta

Tengo varios archivos xml, cuyos nombres están almacenados en otro archivo xml.

Quiero usar xsl para generar un resumen de la combinación de los archivos xml. Recuerdo que había una manera de hacer esto con las extensiones msxml (estoy usando msxml).

Sé que puedo obtener el contenido de cada archivo utilizando select = " document (filename) " pero no estoy seguro de cómo combinar todos estos documentos en uno solo.

21-oct-08 Debería haber mencionado que quiero seguir procesando en el xml combinado, por lo que no es suficiente solo para generar un resultado de la transformación, necesito almacenarlo como un conjunto de nodos en una variable.

¿Fue útil?

Solución

Este es solo un pequeño ejemplo de lo que podría hacer:

file1.xml:

<foo>
<bar>Text from file1</bar>
</foo>

file2.xml:

<foo>
<bar>Text from file2</bar>
</foo>

index.xml:

<index>
<filename>file1.xml</filename>
<filename>file2.xml</filename>

summarize.xsl:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:exsl="http://exslt.org/common"
    extension-element-prefixes="exsl">

  <xsl:variable name="big-doc-rtf">
      <xsl:for-each select="/index/filename">
        <xsl:copy-of select="document(.)"/>
      </xsl:for-each>
  </xsl:variable>

  <xsl:variable name="big-doc" select="exsl:node-set($big-doc-rtf)"/>

  <xsl:template match="/">
    <xsl:element name="summary">
      <xsl:apply-templates select="$big-doc/foo"/>
    </xsl:element>  
  </xsl:template>

  <xsl:template match="foo">
    <xsl:element name="text">
      <xsl:value-of select="bar"/>
    </xsl:element>  
  </xsl:template>

</xsl:stylesheet>

La aplicación de la hoja de estilo a index.xml te da:

<?xml version="1.0" encoding="UTF-8"?><summary><text>Text from file1</text><text>Text from file2</text></summary>

El truco consiste en cargar los diferentes documentos con la función de documento (función de extensión compatible con casi todos los procesadores XSLT 1.0), generar el contenido como parte de un cuerpo variable y luego convertir la variable en un conjunto de nodos para obtener más información. procesamiento.

Otros consejos

Suponga que tiene los nombres de archivo listados en un archivo como este:

<files>
    <file>a.xml</file>
    <file>b.xml</file>
</files>

Entonces podrías usar una hoja de estilo como esta en el archivo anterior:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:template match="/">
        <root>
            <xsl:apply-templates select="files/file"/>                          
        </root>
    </xsl:template>

    <xsl:template match="file">
        <xsl:copy-of select="document(.)"/>
    </xsl:template>
</xsl:stylesheet>

Eche un vistazo al documento ( ) documentación de la función .

Puede usar document () para cargar más documentos XML durante el proceso de transformación. Se cargan como conjuntos de nodos. Eso significa que inicialmente alimentarías el XML que contiene los nombres de archivo para cargar en el XSLT, y lo tomarías desde allí:

<xsl:copy-of select="document(@href)/"/>

Gracias por todas las respuestas. Aquí están las entrañas de la solución que estoy usando con msxml.

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ms="urn:schemas-microsoft-com:xslt">
  <xsl:output method="xml"/>
  <xsl:template match="/">
    <xsl:variable name="combined">
      <xsl:apply-templates select="files"/>
    </xsl:variable>
    <xsl:copy-of select="ms:node-set($combined)"/>
  </xsl:template>
  <xsl:template match="files">
    <multifile>
      <xsl:apply-templates select="file"/>
    </multifile>
  </xsl:template>
  <xsl:template match="file">
    <xsl:copy-of select="document(@name)"/>
  </xsl:template>
</xsl:stylesheet>

Ahora estoy tratando de mejorar el rendimiento, ya que cada archivo tiene aproximadamente 8 MB y la transformación lleva mucho tiempo, pero esa es otra pregunta.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top