Могу ли я использовать XSLT для разбора XML на вложенные файлы?(+ Альтернативные языки / Методы)
Вопрос
Привет всем, у меня есть сильно повторяющиеся данные глубиной в 5 узлов (включая корень), которые необходимо разбить на части.(Я включу быстрый пример через минуту.) Что я хочу сделать, так это разобрать XML-файл размером ~ 5 Мб на более мелкие вложенные файлы на основе узлов 3-й глубины.Но после этого все становится еще сложнее.
Требования к задаче таковы:
- Вложенные файлы должны поддерживать иерархические родительские элементы извлекаемого узла 3-го уровня, включая их атрибуты.
- Вложенные файлы должны сохранять все атрибуты и дочерние узлы.
- Если XSLT не может справиться с заданием, попробуйте выполнить его в Ruby. Если вы не сильны в XSLT, но можете сказать мне, как это сделать на Ruby или даже Python, пожалуйста, не стесняйтесь предоставить ответ на этих языках. (В противном случае попробуйте использовать XSLT или псевдокод.)
Иерархия DOM:
<xml attr="whatever">
<major-group name="whatever">
<minor-group name="whatever">
<another-group name="whatever">
<last-node name="whatever"></last-node>
</another-group>
</minor-group>
</major-group>
</xml>
Который мне нужно разделить на минорная группа элемент, сохраняя при этом как его дочерние элементы, так и прямых родителей, и поместите все это (для каждой второстепенной группы) во внешний файл.У меня есть несколько файлов, которые нужно разделить таким образом.
И...никогда ранее не анализировавший XML в Ruby и только начавший использовать XSLT, я пока не могу написать скрипт для выполнения своей задачи ни с тем, ни с другим.
Мне любопытно посмотреть, справится ли XSLT с этой задачей. :>
Редактировать:
Вот мой результирующий код с возможностью отображения таблицы стилей в начале файла.
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml"/>
<xsl:template match="minor-group">
<xsl:variable name="filename"><xsl:value-of select="concat(@name,'.xml')"/></xsl:variable>
<xsl:result-document href="{$filename}">
<xsl:text disable-output-escaping="yes">
<![CDATA[<?xml-stylesheet type="text/xsl" href="../web.xslt"?>]]>
</xsl:text>
<xml>
<xsl:attribute name="whatever"><xsl:value-of select="../../@whatever" /></xsl:attribute>
<major-group>
<xsl:attribute name="whatever"><xsl:value-of select="../@whatever" /></xsl:attribute>
<xsl:copy-of select="."/>
</major-group>
</xml>
</xsl:result-document>
</xsl:template>
</xsl:stylesheet>
Решение
Чтобы извлечь список элементов "второстепенной группы", потребуется одно из следующих выражений XPath.
/xml/major-group/minor-group (the explicit way) /*/*/* (the generic, any-third-level-element way)
На языке сценариев по вашему выбору прочитайте документ в DOM, создайте цикл по запросу XPath, записывая результаты в разные выходные файлы.
С XSLT 1.0 невозможно сгенерировать более одного выходного документа одновременно.Тем не менее, XSLT 2.0 поддерживает это через <xsl:result-document>
инструкция.
Если в вашем распоряжении есть движок XSLT 2.0, вы могли бы попробовать этот маршрут.Случайная страница, которую я нашел на веб-сайте IBM developerWorks, показывает, как начать: Совет:Создайте несколько файлов в XSLT 2.0
Другие советы
Я не верю, что вы можете разобрать один файл на несколько выходных файлов, используя просто XSLT.
Если бы вы разбили XML на разные XML-файлы с помощью Ruby, а затем применили отдельные XML-файлы к XSLT несколько раз, это должно сработать.