Итак, ключом к пониманию IIB и ESQL является то, что вы смотрите на деревья памяти, построенные из узлов.
Каждый узел имеет указатели / ССЫЛКИ на узлы PARENT, NEXTSIBLING, PREVSIBLING, FIRSTCHILD и LASTCHILD.
Узлы также имеют атрибуты FIELDNAME, FIELDNAMESPACE, FIELDTYPE и FIELDVALUE.
но не в последнюю очередь, что вы строите Деревья вывода, перемещаясь по Деревьям ввода.Дерево среды, которое вы используете, представляет собой специальное долговечное дерево, из которого вы можете как читать, так и записывать.
Итак, в вашем коде InputRoot.SOAP.Body.ns75: processo.ns75:listDocs можно рассматривать как сокращение для инструкций по переходу к узлу ns75: listDocs .Точки "."сообщить интерпретатору ESQL имя дочернего узла текущего узла.Если бы вы говорили кому-то, как перемещаться по узлам, это бы выглядело примерно так:
- Начните с InputRoot .InputRoot - это специальный узел, который автоматически доступен для вас в коде модулей ESQL.
- Перейдите к первому дочернему узлу InputRoot с именем SOAP
- Перейдите к первому дочернему узлу SOAP с именем Body
- Перейдите к первому дочернему узлу Body , которыйимеет имя listDocs и находится в пространстве имен ns75 .
При отсутствии нижнего индекса ESQL предполагает, что вам нужен первый узел, соответствующий указанному имени ns75: listDocs и ns75: listDocs [1] оба ссылаются на один и тот же узел.
Это объясняет, что происходило в вашем коде.Вы всегда переходили к одному и тому же узлу listDocs [1] в деревьях InputRoot и Environment .
@ Код Джерема улучшает то, что вы делали, по крайней мере, перемещаясь по узлам listDocs в дереве ввода.
Для каждой итерации цикла нижний индекс [I] увеличивается и, таким образом, выбирается другой listDocs Node.Узлы listDocs являются братьями и сестрами, поэтому код будет обращаться к первому, второму и третьему экземплярам узлов listDocs .
InputRoot.SOAP.Body.ns75:processo.ns75:listDocs[1] <-- Iteration I=1
InputRoot.SOAP.Body.ns75:processo.ns75:listDocs[2] <-- Iteration I=2
InputRoot.SOAP.Body.ns75:processo.ns75:listDocs[3] <-- Iteration I=3
Чтобы исправить ответ @ Jerem, вынужно будет также использовать подписи в левой части оператора.Выбрав в качестве примера поле description , вам необходимо изменить код следующим образом.
SET Environment.Variables.XMLMessage.return.process.listDocs[I].listTypes.description = InputRoot.SOAP.Body.ns75:processo.ns75:listDocs[I].ns75:listTypes.ns75:description;
Использование подписок рассматривается как исполнение № нет.Представьте, что у вас есть 10 000 listDocs , это приведет к тому, что каждая итерация цикла будет идти вниз по дереву по InputRoot , SOAP , Body , ns75: processo Узлы, а затем через узлы listDocs , пока не найден ns75: listDocs [I] Узел.
Thisозначает, что к тому времени, когда мы вернемся к обработке ns75: listDocs [10000] ему придется многократно обходить все остальные listDocs узлы снова и снова. Фактически мы можем вычислитьон прошел бы (4 x 10 000) + ((10 000 x (10 000 + 1)) / 2) = 50 045 000 узлов
Так что это ССЫЛКИ на помощь и также ответ на ваш вопрос .Попробуйте такой цикл.
DECLARE ns75 NAMESPACE 'http://something.or.other.from.your.wsdl';
DECLARE InListDocsRef REFERENCE TO
InputRoot.SOAP.Body.ns75:processo.ns75:listDocs;
WHILE LASTMOVE(InListDocsRef) DO
DECLARE EnvListDocsRef REFERENCE TO Environment;
CREATE LASTCHILD OF Environment.Variables.XMLMessage.return.process AS EnvListDocsRef NAME 'listDocs';
SET EnvListDocsRef.description = InListDocsRef.ns75:description;
SET EnvListDocsRef.tipoDocumento = InListDocsRef.ns75:DocType;
SET EnvListDocsRef.listTypes.attribute = InListDocsRef.ns75:listTypes.ns75:atribbute;
SET EnvListDocsRef.listTypes.lenght = InListDocsRef.ns75:listTypes.ns75:lenght;
SET EnvListDocsRef.listTypes.description = InListDocsRef.ns75:listTypes.ns75:description;
SET EnvListDocsRef.listTypes.nature = InListDocsRef.ns75:listTypes.ns75:nature;
SET EnvListDocsRef.listTypes.required = InListDocsRef.ns75:listTypes.ns75:required;
MOVE InListDocsRef NEXTSIBLING REPEAT NAME;
END WHILE;
Приведенный выше код охватывает только 4 + 10 000 узлов, то есть 10 тысяч узлов против 50 миллионов узлов.
Несколько других полезных вещей, которые нужно знать об установкессылки:
- Чтобы указать последний элемент, вы можете использовать индекс [<] </strong>.Таким образом, чтобы указать на последний ListItem в совокупности MyList , вы должны кодировать Environment.MyList.ListItem [<] </strong>
- Вы можете использоватьзвездочка * для установки ссылки на элемент в дереве, имя которого вы не знаете, например, Environment.MyAggregate. * указывает на первый дочерний элемент MyAggregate независимо от его имени,
- Вы также можете использовать звездочки *, чтобы выбрать элемент независимо от его пространства имен InListDocsRef. *: ListTypes. *: Description
- Для анонимных элементов пространства имен используйте *: *, но будьте очень осторожны * и *: * - это не одно и то же: первое означает отсутствие пространства имен для любого элемента, а второе означает любое пространство имен для любого элемента.
- Для обработки списков в обратном порядке объедините индекс [<] </strong> с параметром PREVIOUSSIBLING , равным MOVE .
Таким образом, кусок кода для обращения к списку может выглядеть примерно так:
DECLARE MyReverseListItemWalkingRef REFERENCE TO Environment.MyList.ListItem[<];
WHILE LASTMOVE(MyReverseListItemWalkingRef) DO
CREATE LASTCHILD OF OuputRoot.ReversedList.Item NAME 'Description' VALUE MyReverseListItemWalkingRef.Desc;
MOVE MyReverseListItemWalkingRef PREVIOUSSIBLING REPEAT NAME;
END WHILE;
Узнайте, как использовать ССЫЛКИ, они чрезвычайно мощные и один из самых простых вариантов, когда речь идет о производительности.