2008-10-20 3 views
4

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

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

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

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

ответ

3

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

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), для вывода содержимого как части тела переменной, а затем для преобразования переменной в узел- для дальнейшей обработки.

+0

Спасибо. Я знал, что это подход, но не мог вспомнить, как это сделать. Теперь я использую функцию набора узлов msxml, а не exslt, которую вы предлагаете (я знаю, я еретик) и куда-то попадаю. – 2008-10-20 23:18:56

0

Посмотрите на document() function documentation.

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

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

Благодарим за это. Мне нужно добавить дополнительный контент в начале каждого файла xml, чтобы определить, из какого файла он был, поэтому document() не дает мне достаточного контроля. Спасибо в любом случае, поскольку я не знал об этих расширениях document(). – 2008-10-20 23:34:10

2

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

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

Это то, что я изначально пытался, но, насколько я вижу, я не могу использовать эту технику, чтобы поместить xml в переменную, которую я могу обработать дальше. Я получаю сообщение о том, что выбор не является набором узлов. – 2008-10-20 22:38:47

0

Спасибо за все ответы. Вот мужество решения, которое я использую с 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 МБ и трансформация занимает очень много времени, но это другой вопрос.

+0

Я понимаю, что вы только опубликовали «кишки» вашего решения, но, тем не менее, утверждение, такое как , не имеет большого смысла, поскольку вы просто преобразовал RTF в набор узлов и обратно в RTF. работает так же, как и RTF в качестве аргумента. – GerG 2008-10-21 05:10:46