Заполнение файла задания

В начале создания файла нужно объявить, что его содержимое является заданием-графом, для этого открываем тег <Graph>.

Далее нужно открыть тег <Global>, в котором будут описаны метаданные и параметры графа.

Далее открываем элемент <Record>, атрибутами которого можно назначить fieldDelimiter – для объявления разделителя полей записи, и recordDelimiter – для указания символа, разделяющего записи.

Дочерним элементу <Record> является пустой элемент <Field>, у которого нет закрывающего тега. Его используем, чтобы указать имя (name) и тип данных (type) для полей записей.

Теперь поочередно закрываем теги </Record>, </Metadata> и </Global>.

Следующий открывающий тег - <Phase> с атрибутом number, указывающим номер фазы для определения очередности выполнения шагов. В этом примере фаза всего одна, ее номер можно не указывать.

Далее открываем три пустых элемента <Node>, атрибуты которых, описывают имя шага (id), входные и выходные файлы для шагов чтения и записи (file), типы шагов (type) и координаты для отрисовки шагов в инспекторе задач.

У элемента <Node> может быть дочерний элемент <Attr>, которому нужно задать имя name, а внутри записать логическое выражение для фильтрации или метод преобразования данных.

Еще нужно указать пустые теги <Edge> для описания ребер графа. В атрибутах этого элемента можно пояснить, какими ребрами какие шаги связать в этом графе и указать ссылку на метаданные, указанные в начале файла в теге <Metadata>.

В конце закрываем элементы </Phase> и </Graph>.

Получился файл задания:


<?xml version="1.0" encoding="UTF-8"?>
<Graph>
    <Global>
        <Metadata id="ObjectWithPos">
            <Record fieldDelimiter="|" recordDelimiter="\n">
                <Field name="a" type="string"/>
                <Field name="b" type="integer"/>
                <Field name="c" type="float"/>
            </Record>
        </Metadata>
    </Global>
    
    <Phase number="0">
        <Node id="reader0" guiX="50"   guiY="100" guiName="FlatFileReader" file="data-in/others/example_01_in1.txt"   type="FlatFileReader"/>
        <Node id="reader1" guiX="50"   guiY="300" guiName="FlatFileReader" file="data-in/others/example_01_in2.txt"   type="FlatFileReader"/>
        <Node id="writer0" guiX="1050" guiY="300" guiName="FlatFileWriter" file="data-out/others/example_01_out1.txt" type="FlatFileWriter"/>
        <Node id="writer1" guiX="650"  guiY="100" guiName="FlatFileWriter" file="data-out/others/example_01_out2.txt" type="FlatFileWriter"/>
        <Node id="concat"  guiX="250"  guiY="200" guiName="Concat" type="Concat"/>
        <Node id="copy"    guiX="450"  guiY="200" guiName="Copy" type="Copy"/>
        <Node id="sort"    guiX="650"  guiY="300" guiName="FileSortNode" sortKey="c(d)" type="FileSortNode"/><!--"d" - descending-->
        
        <Node id="filter"  guiX="850" guiY="300" guiName="FilterNode" type="FilterNode">
            <Attr name="filterExpression">
                <![CDATA[//#Rust:closure
                |input| input.a.chars().count() < 15
                ]]>
            </Attr>
        </Node>
    
        <Edge id="edge0" fromNode="reader0:0" toNode="concat:0"/>
        <Edge id="edge1" fromNode="reader1:0" toNode="concat:1"/>
        <Edge id="edge2" fromNode="concat:0"  toNode="copy:0"/>
        <Edge id="edge6" fromNode="copy:0"    toNode="writer1:0" metadata="ObjectWithPos"/>
        <Edge id="edge5" fromNode="copy:1"    toNode="sort:0"/>
        <Edge id="edge3" fromNode="sort:0"    toNode="filter:0"/>
        <Edge id="edge4" fromNode="filter:0"  toNode="writer0:0" metadata="ObjectWithPos"/>
    </Phase>
</Graph>