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