Pergunta

Eu tenho vários arquivos XML, os nomes dos que são armazenadas em outro arquivo xml.

Eu quero usar XSL para produzir um resumo da combinação dos arquivos XML. Lembro-me que havia uma maneira de fazer isso com as extensões MSXML (estou usando msxml).

Eu sei que posso obter o conteúdo de cada arquivo usando select="document(filename)" mas eu não tenho certeza de como combinar todos estes documentos em um só.

21-Oct-08 eu deveria ter mencionado que eu quero fazer processamento adicional no xml combinado, por isso não é suficiente para a saída de apenas-lo a partir da transformação, eu preciso armazená-lo como um conjunto de nós em uma variável.

Foi útil?

Solução

Aqui é apenas um pequeno exemplo do que você poderia fazer:

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>

Aplicar a folha de estilo para index.xml dá-lhe:

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

O truque é carregar os diferentes documentos com a função de documento (função de extensão suportado por quase todos XSLT 1.0 processadores), a saída do conteúdo como parte de um corpo variável e, em seguida, para converter a variável de um conjunto de nós para posterior processamento.

Outras dicas

Suponha que você tenha os nomes de arquivos listados em um arquivo como este:

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

Em seguida, você poderia usar uma folha de estilo como este no arquivo acima:

<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>

Tenha um olhar para o document() documentação função .

Você pode usar document() para carregar outros documentos XML durante o processo de transformação. Eles são carregados como conjuntos de nodos. Isso significa que você seria inicialmente alimentam o XML que contém os nomes de arquivo de carga para o XSLT, e levá-la de lá:

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

Obrigado por todas as respostas. Aqui está a coragem da solução que eu estou usando com 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>

Agora eu estou tentando melhorar o desempenho como cada arquivo é de cerca de 8 MB e a transformação está tomando um tempo muito longo, mas isso é outra questão.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top