Объединение файлов xml

У меня есть несколько файлов xml, имена которых хранятся в другом файле xml.

Я хочу использовать xsl для получения сводной информации о комбинации файлов xml. Я помню, что был способ сделать это с помощью расширений msxml (я использую msxml).

Я знаю, что могу получить содержимое каждого файла с помощью select="document(filename)", но я не уверен, как объединить все эти документы в один.

21 октября 2008 г. Я должен был упомянуть, что хочу продолжить обработку объединенного xml, поэтому недостаточно просто вывести его из преобразования, мне нужно сохранить его как узел, установленный в переменной.


person Richard A    schedule 20.10.2008    source источник


Ответы (4)


Вот лишь небольшой пример того, что вы могли сделать:

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>

Применение таблицы стилей к index.xml дает вам:

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

Уловка состоит в том, чтобы загрузить различные документы с помощью функции документа (функция расширения поддерживается почти всеми процессорами XSLT 1.0), чтобы вывести содержимое как часть тела переменной, а затем преобразовать переменную в набор узлов для дальнейшей обработки.

person GerG    schedule 20.10.2008
comment
Спасибо. Я знал, что это был подход, но не мог вспомнить, как это сделать. Теперь я использую функцию msxml node-set вместо exslt, которую вы предлагаете (я знаю, я еретик), и куда-то добираюсь. - person Richard A; 21.10.2008

Предположим, что у вас есть имена файлов, перечисленные в таком файле:

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

Затем вы можете использовать такую ​​таблицу стилей в приведенном выше файле:

<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>
person Community    schedule 20.10.2008
comment
Это то, что я изначально пробовал, но, насколько я понимаю, я не могу использовать эту технику для помещения xml в переменную, которую я могу обработать дальше. Я получаю сообщение об ошибке, говорящее, что выбранный элемент не является набором узлов. - person Richard A; 21.10.2008

Ознакомьтесь с document() документацией по функциям.

Вы можете использовать document() для загрузки других XML-документов в процессе преобразования. Они загружаются как наборы узлов. Это означает, что вы сначала загрузите XML, содержащий имена файлов для загрузки в XSLT, и возьмете его оттуда:

<xsl:copy-of select="document(@href)/"/>
person Tomalak    schedule 20.10.2008
comment
Спасибо за это. Мне нужно добавить дополнительный контент в начало xml каждого файла, чтобы определить, из какого файла он был, поэтому document () не дает мне достаточного контроля. В любом случае спасибо, так как я не знал об этих расширениях для document (). - person Richard A; 21.10.2008

Спасибо за ответы на все вопросы. Вот внутренняя часть решения, которое я использую с 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>

Теперь я пытаюсь повысить производительность, так как размер каждого файла составляет около 8 МБ, а преобразование занимает очень много времени, но это уже другой вопрос.

person Richard A    schedule 21.10.2008
comment
Я понимаю, что вы опубликовали только «внутренности» своего решения, но, тем не менее, такой оператор, как ‹xsl: copy-of select = ms: node-set ($ комбинированный) /›, не имеет большого смысла, поскольку вы только что преобразовали RTF в набор узлов и обратно в RTF. ‹Xsl: copy-of› работает точно так же, как с аргументом RTF. - person GerG; 21.10.2008
comment
Для повышения производительности я бы фактически предложил не использовать таблицу стилей в зависимости от количества информации, которую вы хотите извлечь из отдельных файлов. Если вам просто нужно объединить их (с удалением XML-заголовка), тогда подойдет и простой скрипт на предпочитаемом вами языке. - person GerG; 21.10.2008
comment
Что касается node-set (), мне нужен вывод в виде набора узлов, над которым я могу выполнять дальнейшую обработку. Когда я пытаюсь поместить вывод в атрибут select без node-set (), процессор (справедливо) жалуется, что это не набор узлов. - person Richard A; 30.10.2008
comment
Спасибо за предложение просто объединить файлы. Я тоже думал об этом. В противном случае я мог бы обрабатывать файлы через XMLDOM с помощью Delphi, поскольку мне нужно выполнить другую программную обработку до и после преобразования. - person Richard A; 30.10.2008