Сценарий для переформатирования файла XML
Вопрос
Я пытаюсь изменить файл XML из одного формата на другое и не имею никакой подсказки для того, как написать сценарий для него. Может кто-нибудь помочь, пожалуйста?
Исходный файл выглядит так:
<Record>
<FieldValue fieldName="rapportage_nihil" fieldValue="false" fieldValueIsNull="false" fieldValueNatural="false"/>
<FieldValue fieldName="periode" fieldValue="2009-23-31" fieldValueIsNull="false" fieldValueNatural="2009-10-31 00:23:23"/>
<FieldValue fieldName="formulierid" fieldValue="9001HK1V10" fieldValueIsNull="false" fieldValueNatural="9001HK1V10"/>
<FieldValue fieldName="versie" fieldValue="1" fieldValueIsNull="false" fieldValueNatural="1"/>
<FieldValue fieldName="frequentie" fieldValue="M" fieldValueIsNull="false" fieldValueNatural="M"/>
<FieldValue fieldName="variant_type" fieldValue="Landen" fieldValueIsNull="false" fieldValueNatural="Landen"/>
<FieldValue fieldName="value" fieldValue="5F" fieldValueIsNull="false" fieldValueNatural="5F"/>
<FieldValue fieldName="post_value" fieldValue="0.00" fieldValueIsNull="false" fieldValueNatural="1.037E-4"/>
<FieldValue fieldName="cube" fieldValue="c01" fieldValueIsNull="false" fieldValueNatural="c01"/>
<FieldValue fieldName="rij" fieldValue="r_24_100_1_000_0" fieldValueIsNull="false" fieldValueNatural="r_24_100_1_000_0"/>
<FieldValue fieldName="kolom" fieldValue="c_2250_SPU" fieldValueIsNull="false" fieldValueNatural="c_2250_SPU"/>
</Record>
<Record>
<FieldValue fieldName="rapportage_nihil" fieldValue="false" fieldValueIsNull="false" fieldValueNatural="false"/>
<FieldValue fieldName="periode" fieldValue="2009-23-31" fieldValueIsNull="false" fieldValueNatural="2009-10-31 00:23:23"/>
<FieldValue fieldName="formulierid" fieldValue="9001HK1V10" fieldValueIsNull="false" fieldValueNatural="9001HK1V10"/>
<FieldValue fieldName="versie" fieldValue="1" fieldValueIsNull="false" fieldValueNatural="1"/>
<FieldValue fieldName="frequentie" fieldValue="M" fieldValueIsNull="false" fieldValueNatural="M"/>
<FieldValue fieldName="variant_type" fieldValue="Landen" fieldValueIsNull="false" fieldValueNatural="Landen"/>
<FieldValue fieldName="value" fieldValue="5F" fieldValueIsNull="false" fieldValueNatural="5F"/>
<FieldValue fieldName="post_value" fieldValue="0.00" fieldValueIsNull="false" fieldValueNatural="1.037E-4"/>
<FieldValue fieldName="cube" fieldValue="c01" fieldValueIsNull="false" fieldValueNatural="c01"/>
<FieldValue fieldName="rij" fieldValue="r_24_108_0_000_0" fieldValueIsNull="false" fieldValueNatural="r_24_108_0_000_0"/>
<FieldValue fieldName="kolom" fieldValue="c_2250_SPU" fieldValueIsNull="false" fieldValueNatural="c_2250_SPU"/>
</Record>
<Record>
<FieldValue fieldName="rapportage_nihil" fieldValue="false" fieldValueIsNull="false" fieldValueNatural="false"/>
<FieldValue fieldName="periode" fieldValue="2009-23-31" fieldValueIsNull="false" fieldValueNatural="2009-10-31 00:23:23"/>
<FieldValue fieldName="formulierid" fieldValue="9001HK1V10" fieldValueIsNull="false" fieldValueNatural="9001HK1V10"/>
<FieldValue fieldName="versie" fieldValue="1" fieldValueIsNull="false" fieldValueNatural="1"/>
<FieldValue fieldName="frequentie" fieldValue="M" fieldValueIsNull="false" fieldValueNatural="M"/>
<FieldValue fieldName="variant_type" fieldValue="Landen" fieldValueIsNull="false" fieldValueNatural="Landen"/>
<FieldValue fieldName="value" fieldValue="5F" fieldValueIsNull="false" fieldValueNatural="5F"/>
<FieldValue fieldName="post_value" fieldValue="0.00" fieldValueIsNull="false" fieldValueNatural="1.6049E-4"/>
<FieldValue fieldName="cube" fieldValue="c01" fieldValueIsNull="false" fieldValueNatural="c01"/>
<FieldValue fieldName="rij" fieldValue="r_06_000_1_010_0" fieldValueIsNull="false" fieldValueNatural="r_06_000_1_010_0"/>
<FieldValue fieldName="kolom" fieldValue="c_2250_SPU" fieldValueIsNull="false" fieldValueNatural="c_2250_SPU"/>
</Record>
Это формат, который мне нужен в результате:
<bestand registratienummer="123">
<rapportage nihil="false" periode="2009-23-31" formulierid="9001HK1V10" versie="1" frequentie="M">
<variant type="Landen" value="5F" />
<post value="0.00" cube="c01" rij="r_24_100_1_000_0" kolom="c_2250_SPU" />
</rapportage>
<rapportage nihil="false" periode="2009-23-31" formulierid="9001HK1V10" versie="1" frequentie="M">
<variant type="Landen" value="5F" />
<post value="0.00" cube="c01" rij="r_24_108_0_000_0" kolom="c_2250_SPU" />
</rapportage>
<rapportage nihil="false" periode="2009-23-31" formulierid="9001HK1V10" versie="1" frequentie="M">
<variant type="Landen" value="5F" />
<post value="0.00" cube="c01" rij="r_06_000_1_010_0" kolom="c_2250_SPU" />
</rapportage>
</bestand>
Большое спасибо!
Решение
XSLT предназначен для именно этой цели. Вы можете преобразовать любой четко определенный файл XML в любой другой формат простого текста, включая другую структуру XML. Получите, например, XSLTProc, напишите скрипт, и вы закончите.
Если вам нужно сначала изучать XSLT, вот хорошая отправная точка: http://www.w3schools.com/xsl/ (Это руководство дает примеры для преобразования в XHTML, но вам просто нужно использовать свои целевые теги XML вместо тегов XHTML ...).
Это может быть хорошим сценарием для начала (извините, но у меня нет времени, чтобы дать вам полноценный сценарий здесь):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" encoding="utf-8" />
<xsl:template match="/">
<bestand registratienummer="123">
<apply-templates select="//Record"/>
</bestand>
</xsl:template>
<xsl:template match="Record">
<xsl:variable name="nihil" select="FieldValue[@fieldName='rapportage_nihil']/@fieldValue"/>
<!-- add more variable lookups here. you need XPath for that. -->
<rapportage nihil="{$nihil}" periode="{$periode}">
<!-- add more output here -->
</rapportage>
</xsl:template>
</xsl:stylesheet>
Вы могли бы дать xsltproc. Этот стильют и ваш источник XML документ даст вам новый XML-файл. Может быть, вам необходимо убедиться, что ваш файл XML исходного XML определен, то есть содержит один Корневой элемент. Ваш пример не похоже, что у него есть один, вам может потребоваться окружить его произвольным элементом.
Чтобы разработать немного на XSLT и сценарии: представьте, что у вас есть два указателя. Один в сценарии XSLT, один в исходном файле XML. XSLT - это все о «применении шаблонов», и он всегда использовал бы шаблон, который является ближайшим матчем (подумайте о шаблонах как какую-то функцию).
Сначала ближайший матч будет корневым элементом, поэтому указатель XSLT начнется в шаблоне с match="/"
. Отказ Указатель XML находится в корневом элементе (псевдоним «тег») исходного документа XML. Любой элемент, который нет начиная с xsl:
будет рассматриваться как выходной элемент. Итак, прежде всего, XSLTProc выводится <bestand>
элемент.
Тогда указатель XSLT идет дальше и находит <apply-templates>
Выбор всех элементов сопоставления //Record
(двойная косой обозначает «на любой глубине»). Для каждого <Record>
Элемент, он бы «вызвал» соответствующий шаблон. Здесь ближайший матч будет <xsl:template match="Record">
.
Так что указатель XSLT перепрыгивает на шаблон, указатель XML на первый <Record>
. Отказ Затем переменная (nihil
) объявлен, содержащий некоторую информацию из записи, которая выбрана от указателя XML напротив более глубокий в структуру XML исходного документа с использованием выражения XPath. Экспрессия XPath говорит: «Выбрать из элемента FieldValue
который имеет атрибут fieldName
со значением 'rapportage_nihil'
Значение атрибута fieldValue
«(Подумайте об этом, как предложение SQL, где для данных XML; атрибуты сбрасываются здесь с @
).
Вам необходимо скопировать, вставить и изменить эту строку для каждой необходимости информации в вашем выходе. Затем выходной элемент <rapportage>
оценивается, подставляя каждую переменную (например, {$nihil}
) со своими соответствующими значениями, установленными выше с <xsl:variable>
. Отказ Вам нужно добавить элементы внутри <rapportage>
элемент в том же моде, что и <rapportage>
элемент. Затем шаблон на его конце и следующий <Record>
будет поставлен через шаблон.