Вопрос
У меня есть несколько XML-файлов, имена которых хранятся в другом XML-файле.
Я хочу использовать xsl для создания сводки по комбинации XML-файлов.Я помню, что был способ сделать это с помощью расширений msxml (я использую msxml).
Я знаю, что могу получить содержимое каждого файла, используя select="document(filename)"
но я не уверен, как объединить все эти документы в один.
21-Oct-08 Я должен был упомянуть, что я хочу выполнить дальнейшую обработку объединенного xml, поэтому недостаточно просто вывести его из преобразования, мне нужно сохранить его как набор узлов в переменной.
Решение
Вот лишь небольшой пример того, что вы мог бы делай:
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>
подведите итог.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>
Хитрость заключается в том, чтобы загрузить различные документы с помощью функции document (функция расширения, поддерживаемая почти всеми процессорами XSLT 1.0), вывести содержимое как часть тела переменной, а затем преобразовать переменную в набор узлов для дальнейшей обработки.
Другие советы
Предположим, что у вас есть имена файлов, перечисленные в файле, подобном этому:
<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>
Просмотрите документ ( )
документация по функциям .
Вы можете использовать document ()
для загрузки дополнительных документов XML в процессе преобразования. Они загружаются как наборы узлов. Это означает, что вы сначала передадите XML, содержащий имена файлов, для загрузки в XSLT, и получите его оттуда:
<xsl:copy-of select="document(@href)/"/>
Спасибо за все ответы. Вот суть решения, которое я использую с 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 МБ, а преобразование занимает очень много времени, но это другой вопрос.