Скрипт для переформатирования XML-файла - PullRequest
1 голос
/ 21 апреля 2010

Я пытаюсь изменить 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>  

Большое спасибо!

1 Ответ

4 голосов
/ 21 апреля 2010

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

Чтобы немного рассказать о 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 WHERE для данных XML; Атрибутыздесь с префиксом @).

Вам необходимо скопировать, вставить и изменить эту строку для каждой информации, которая вам нужна в выходном документе.Затем оценивается выходной элемент <rapportage>, заменяя каждую переменную (например, {$nihil}) их соответствующими значениями, установленными выше, на <xsl:variable>.Вы должны добавить элементы внутри элемента <rapportage> таким же образом, как элемент <rapportage>.Тогда шаблон в конце, и следующий <Record> будет пропущен через шаблон.

...