Im letzten Artikel RQL-Befehle in benutzerdefinierten Aufträgen: Platzhalter aus dieser Serie haben wir uns mit der Platzhalter- und Ersetzungslogik innerhalb benutzerdefinierten Aufträgen beschäftigt. Nun kommen wir zu den s.g. Kontrollstrukturen und beschäftigen uns erstmal mit der for-Schleife.
Diese Kontrollstruktur besteht aus einem RQL-Statement, das eine Ergebnisliste und eine Reihe von RQL-Statements zurückgibt, die für jedes Ergebnis in der Liste ausgeführt werden. Das RQL-Statement hat die folgende Struktur:
<RQLCOMMAND type="for" name="Name des Objekts, das die Ergebnisliste enthält."> <LIST> <!-- RQL, das die Ergebnismenge zurückgibt. --> </LIST> <OBJECTIVES> <!-- RQLs, die für jedes Ergebnis verwendet werden. --> </OBJECTIVES> </RQLCOMMAND>
Setzt man das Attribut type im RQLCOMMAND-Knoten auf for, dann wird die Funktion FOR-Schleife aktiviert. Im Attribut name wird nun der Name des Knotens definiert, welcher die Ergebnisse enthält.
Für den LIST-Knoten muss man nun den RQL-Befehl angeben, der die Ergebnismenge zurückgibt. Im Unterknoten OBJECTIVES legt man nun fest, welche Platzhalter in den RQL-Befehlen aus dem diese Ergebnisse verwendet werden.
Beispiele:
<RQLCOMMAND type="for" name="PROJECTS"> <!-- Deletes publication job reports from the database (IO_EXR) and publication log files from the Management Server instance this job runs on. --> <!-- List all projects to apply the OBJECTIVES commands to them. --> <LIST> <IODATA loginguid="[!guid_login!]" sessionkey=""> <ADMINISTRATION> <USER guid="[!guid_user!]"> <PROJECTS action="list" extendedinfo="1" /> </USER> </ADMINISTRATION> </IODATA> </LIST> <!-- The commands in the OBJECTIVES element are executed for all result elements of the LIST element --> <OBJECTIVES> <!-- Connect to the current project --> <IODATA loginguid="[!guid_login!]"> <ADMINISTRATION action="validate" guid="[!guid_login!]"> <PROJECT guid="[!guid_project!]" /> </ADMINISTRATION> </IODATA> <!-- Remove the publishing reports and and logfiles for the current project if they are older than seven days (days="7") --> <IODATA loginguid="[!guid_login!]" sessionkey="[!guid_login!]"> <PROJECT guid="[!guid_project!]" sessionkey="[!guid_login!]"> <EXPORTREPORT days="7" action="deleteall" deletelogfiles="1" /> </PROJECT> </IODATA> </OBJECTIVES> </RQLCOMMAND>
Der RQL-Befehl im Unterknoten LIST gibt die Projekte zurück, auf die der Benutzer Zugriff hat. Mit name="PROJECTS" im RQLCOMMAND Knoten wird eine Suche nach dem RQL-Ergebnis für den Knotennamen PROJECTS durchgeführt, der die Ergebnismenge enthalten sollte.
Die Antwort-RQL liefert als Ergebnis den PROJECTS-Knoten sowie eine Liste seiner Unterknoten mit den Namen PROJECT. Das Unterknoten-Attribut guid wird anschließend auf die RQL-Befehle, die in OBJECTIVES enthalten sind, angewendet und ersetzt die entsprechenden [!guid_project!]-Platzhalter.
Das läuft nun wieder wie folgt ab:
REQEUST-001:
<IODATA> <ADMINISTRATION action="login" name="Admin" checkonly="1"/> </IODATA>
Erstmal wird innnerhalb des benutzerdefinierten Auftrags eine Anmeldung ausgeführt.
RESPONSE-001:
<IODATA> <LOGIN guid="E1B3501F8E3C48FB91521EA0A4011FC5" server="WIN-OTWSM-16X" serverguid="80912FB47C834A289312F58C49B5CF3D" userkey="" usertoken="" name="Admin"/> <USER guid="7C4F7FF5744C43A4B537DB97BF4A815D" name="Admin" fullname="Administrator" id="1" flags1="0" flags2="32768" dialoglanguageid="DEU" preferrededitor="0" taskpreviewmode="2" invertdirectedit="0" invertdropmode="" dialogtextdirection="" languageid="DEU" showstarthelp="0" lcid="1031"> <MODULES> <MODULE guid="4656D1A8354A4812BCA17C2564A00D2B" id="servermanager" name="13772" /> <MODULE guid="19234F30BB984D938520CDC5E0B1EAD4" id="cms" name="0"> <MODULES> <MODULE guid="37542EE2585545D188BEFB6801B1C971" id="smarttree" name="13769" /> <MODULE guid="552284EC17D24267A813012561180A26" id="templateeditor" name="13771" /> <MODULE guid="30265560D1E3462DB808699637681497" id="smartedit" name="13770" /> <MODULE guid="92E972B2FB87428cAC58C8DC8450B7E5" id="tasks" name="2215" /> <MODULE guid="EAA81F8C9D544633B3B94254F537B3BC" id="search" name="18274" /> </MODULES> </MODULE> <MODULE guid="E3E1678FB2E14470B4D2951123B44E18" id="assets" name="13773" /> </MODULES> <LASTMODULES> <MODULE project="FCD226ACB77B468C9DDAE2F4B472D4D3" projectname="Xample" lastid="smarttree" lastguid="37542EE2585545D188BEFB6801B1C971" id="smarttree" guid="37542EE2585545D188BEFB6801B1C971" last="0" /> <MODULE project="92EAB46013E04748AD29910824795114" projectname="New project" lastid="servermanager" lastguid="4656D1A8354A4812BCA17C2564A00D2B" id="servermanager" guid="4656D1A8354A4812BCA17C2564A00D2B" last="0" /> <MODULE project="EA11225008D94B6D82403EC0837F83BC" projectname="Product Information Catalog" lastid="smarttree" lastguid="37542EE2585545D188BEFB6801B1C971" id="smarttree" guid="37542EE2585545D188BEFB6801B1C971" last="0" /> <MODULE project="3743BCA1BF564DDEB1CD09C356D01203" projectname="OTCS Ticket 3102325" lastid="servermanager" lastguid="4656D1A8354A4812BCA17C2564A00D2B" id="servermanager" guid="4656D1A8354A4812BCA17C2564A00D2B" last="0" /> <MODULE project="9E1937E3D3B24F5FA01BBE10A7ADFFCE" projectname="Demo-Projekt Schlagworte und Navigation" lastid="servermanager" lastguid="4656D1A8354A4812BCA17C2564A00D2B" id="servermanager" guid="4656D1A8354A4812BCA17C2564A00D2B" last="0" /> <MODULE project="78E3E8867DB6467EAABC38703C3C882C" projectname="OTCS Ticket 4067703" lastid="smarttree" lastguid="37542EE2585545D188BEFB6801B1C971" id="smarttree" guid="37542EE2585545D188BEFB6801B1C971" last="0" /> <MODULE project="BA6B979C93FD4875AFE694CC5288745C" projectname="OT-WSM-Blog" lastid="servermanager" lastguid="4656D1A8354A4812BCA17C2564A00D2B" id="servermanager" guid="4656D1A8354A4812BCA17C2564A00D2B" last="1" /> <MODULE project="3AF47BB37CA24C569673C8BBE14C3C38" projectname="RQLCommands" lastid="servermanager" lastguid="4656D1A8354A4812BCA17C2564A00D2B" id="servermanager" guid="4656D1A8354A4812BCA17C2564A00D2B" last="0" /> <MODULE project="1686D0DD0E674602B47EF55689A7085F" projectname="Collecting Navigation" lastid="smarttree" lastguid="37542EE2585545D188BEFB6801B1C971" id="smarttree" guid="37542EE2585545D188BEFB6801B1C971" last="0" /> </LASTMODULES> </USER> </IODATA>
REQEUST-002:
Nun wird die for-Schleife ausgeführt, jedoch werden zuvor die Attribute mit den Werten aus dem vorherigen Ergebnis (Anmeldung) befüllt:
<RQLCOMMAND type="for" name="PROJECTS"> <LIST> <IODATA loginguid="[!guid_login!]" sessionkey=""> <ADMINISTRATION> <USER guid="[!guid_user!]"> <PROJECTS action="list" extendedinfo="1" /> </USER> </ADMINISTRATION> </IODATA> </LIST> ...
über die automatische Ersetzung während der Laufzeit mit dem jeweils korrekten Wert befüllt:
<IODATA loginguid="E1B3501F8E3C48FB91521EA0A4011FC5" sessionkey=""> <ADMINISTRATION> <USER guid="7C4F7FF5744C43A4B537DB97BF4A815D"> <PROJECTS action="list" extendedinfo="1" /> </USER> </ADMINISTRATION> </IODATA>
RESPONSE-002:
<IODATA> <USER guid="7C4F7FF5744C43A4B537DB97BF4A815D"> <PROJECTS action="list" extendedinfo="1" parentguid="7C4F7FF5744C43A4B537DB97BF4A815D" parenttype="USR" newprojectcreatable="1"> <PROJECT guid="1686D0DD0E674602B47EF55689A7085F" name="Collecting Navigation" servername="WIN-OTWSM-16X" server="WIN-OTWSM-16X" versioning="-1" archive="-1" testproject="1" inhibitlevel="0" lockinfo="" checkdatabase="016.224" lockedbysystem="0" inhibit="0" userlevel="1" templateeditorright="-1" languagemanagerright="0" denyprojectsettings="0" denyadministerpublication="1" /> <PROJECT guid="9E1937E3D3B24F5FA01BBE10A7ADFFCE" name="Demo-Projekt Schlagworte und Navigation" servername="WIN-OTWSM-16X" server="WIN-OTWSM-16X" versioning="-1" archive="-1" testproject="1" inhibitlevel="16" lockinfo="This project has been automatically locked against publication after being updated." checkdatabase="016.224" lockedbysystem="0" inhibit="0" userlevel="1" templateeditorright="-1" languagemanagerright="0" denyprojectsettings="0" denyadministerpublication="0" /> <PROJECT guid="92EAB46013E04748AD29910824795114" name="New project" servername="WIN-OTWSM-16X" server="WIN-OTWSM-16X" versioning="-1" archive="-1" testproject="1" inhibitlevel="-1" lockinfo="test" checkdatabase="016.224" lockedbysystem="0" inhibit="1" userlevel="1" templateeditorright="0" languagemanagerright="0" denyprojectsettings="0" denyadministerpublication="0" /> <PROJECT guid="3743BCA1BF564DDEB1CD09C356D01203" name="OTCS Ticket 3102325" servername="WIN-OTWSM-16X" server="WIN-OTWSM-16X" versioning="-1" archive="-1" testproject="1" inhibitlevel="16" lockinfo="This project has been automatically locked against publication after being updated." checkdatabase="016.224" lockedbysystem="0" inhibit="0" userlevel="1" templateeditorright="-1" languagemanagerright="0" denyprojectsettings="0" denyadministerpublication="0" /> <PROJECT guid="78E3E8867DB6467EAABC38703C3C882C" name="OTCS Ticket 4067703" servername="WIN-OTWSM-16X" server="WIN-OTWSM-16X" versioning="-1" archive="-1" testproject="1" inhibitlevel="16" lockinfo="This project has been automatically locked against publication after being updated." checkdatabase="016.224" lockedbysystem="0" inhibit="0" userlevel="1" templateeditorright="-1" languagemanagerright="0" denyprojectsettings="0" denyadministerpublication="0" /> <PROJECT guid="BA6B979C93FD4875AFE694CC5288745C" name="OT-WSM-Blog" servername="WIN-OTWSM-16X" server="WIN-OTWSM-16X" versioning="-1" archive="-1" testproject="1" inhibitlevel="0" lockinfo="" checkdatabase="016.224" lockedbysystem="0" inhibit="0" userlevel="1" templateeditorright="-1" languagemanagerright="0" denyprojectsettings="0" denyadministerpublication="0" /> <PROJECT guid="EA11225008D94B6D82403EC0837F83BC" name="Product Information Catalog" servername="WIN-OTWSM-16X" server="WIN-OTWSM-16X" versioning="-1" archive="-1" testproject="1" inhibitlevel="16" lockinfo="This project has been automatically locked against publication after being updated." checkdatabase="016.224" lockedbysystem="0" inhibit="0" userlevel="1" templateeditorright="-1" languagemanagerright="0" denyprojectsettings="0" denyadministerpublication="0" /> <PROJECT guid="3AF47BB37CA24C569673C8BBE14C3C38" name="RQLCommands" servername="WIN-OTWSM-16X" server="WIN-OTWSM-16X" versioning="-1" archive="-1" testproject="1" inhibitlevel="0" lockinfo="" checkdatabase="016.224" lockedbysystem="0" inhibit="0" userlevel="1" templateeditorright="-1" languagemanagerright="0" denyprojectsettings="0" denyadministerpublication="0" /> <PROJECT guid="FCD226ACB77B468C9DDAE2F4B472D4D3" name="Xample" servername="WIN-OTWSM-16X" server="WIN-OTWSM-16X" versioning="-1" archive="-1" testproject="0" inhibitlevel="16" lockinfo="This project has been automatically locked against publication after being updated." checkdatabase="016.224" lockedbysystem="0" inhibit="0" userlevel="1" templateeditorright="-1" languagemanagerright="0" denyprojectsettings="0" denyadministerpublication="0" /> <PROJECT guid="1ADD892F54F448788F55CBFF92CFF02D" name="Xample 16.0.3" servername="WIN-OTWSM-16X" server="WIN-OTWSM-16X" versioning="-1" archive="-1" testproject="1" inhibitlevel="16" lockinfo="This project has been automatically locked against publication after being imported." checkdatabase="016.224" lockedbysystem="0" inhibit="0" userlevel="1" templateeditorright="-1" languagemanagerright="0" denyprojectsettings="0" denyadministerpublication="0" /> <PROJECT guid="CD554865D941499FAF6BF5F05B1ABE2B" name="Xample 16.0.3 (ASPX)" servername="WIN-OTWSM-16X" server="WIN-OTWSM-16X" versioning="-1" archive="-1" testproject="1" inhibitlevel="16" lockinfo="This project has been automatically locked against publication after being imported." checkdatabase="016.224" lockedbysystem="0" inhibit="0" userlevel="1" templateeditorright="-1" languagemanagerright="0" denyprojectsettings="0" denyadministerpublication="0" /> </PROJECTS> </USER> </IODATA>
Dieses Ergebnis wird nun im nachfolgenden Abschnitt OBJECTIVES verarbeitet. Der OBJECTIVES-Anschnitt wird so oft wiederholt, wie Ergebnisse aus der Abfrage zuvor gibt.
REQEUST-003:
Auch hier werden die Attribute entsprechend mit den jeweiligen Werten aus dem Ergbnis ersetzt:
... <OBJECTIVES> <!-- Connect to the current project --> <IODATA loginguid="[!guid_login!]"> <ADMINISTRATION action="validate" guid="[!guid_login!]"> <PROJECT guid="[!guid_project!]" /> </ADMINISTRATION> </IODATA> ...
... <IODATA loginguid="E1B3501F8E3C48FB91521EA0A4011FC5"> <ADMINISTRATION action="validate" guid="E1B3501F8E3C48FB91521EA0A4011FC5" checkonly="1"> <PROJECT guid="1686D0DD0E674602B47EF55689A7085F" /> </ADMINISTRATION> </IODATA> ...
RESPONSE-003:
<IODATA> <PROJECT guid="1686D0DD0E674602B47EF55689A7085F" name="Collecting Navigation" reddotstartpageguid="FFB318284E784C7B9FFA2D6B48E04378" flags="7" versioning="1" archive="1" testproject="1" filestream="0" useexterneditor="1" externeditor="CKEditor" externeditorurl="" requestexterneditortext="" setnamesonlyinmainlanguage="0" templaterelease="1" contentclassversioning="2" ignoreusertexteditorpreferences="0" liveserverguid="" donotloadtexteditorinform="0" preventpageclosing="0" executevirtualpath="" executephysicalpath="" assetfilenamerestriction="/^[^\\\/<>:*?"&%\+]{4,150}$/i" pagefilenamerestriction="/^[a-z0-9_\-\.]*$/i" assetfileendingsfortexteditor="jpg; gif; png; svg" limitassetstofileendings="1" mainlanguagevariantid="DEU" /> <USER guid="7C4F7FF5744C43A4B537DB97BF4A815D" userid="1" flags1="2088984" flags2="48716" maxlevel="1" isservermanager="-1" dialoglanguageid="DEU" lcid="1031" dialoglcid="1031" languagevariantlcid="1031" projectguid="1686D0DD0E674602B47EF55689A7085F" te="-1" level="1" denyprojectsettings="0" denyadministerpublication="1" lm="0" mainlanguagevariantid="DEU" languagevariantid="DEU" languagevariantguid="AAE987B097E548DF934A9432892FDDBA" mainlanguagevariantguid="AAE987B097E548DF934A9432892FDDBA" rights1="-1" rights2="-1" rights3="-1" rights4="-1" /> <SERVER guid="17BED1BDBBD94CF0AC897187C6FB25AE" name="" key="E1B3501F8E3C48FB91521EA0A4011FC5" /> <LICENSE userguid="7C4F7FF5744C43A4B537DB97BF4A815D" projectguid="1686D0DD0E674602B47EF55689A7085F" te="-1" lm="0" denyprojectsettings="0" denyadministerpublication="1" level="1" id="cms" /> </IODATA>
REQEUST-004:
Auch die Platzhalter aus dem zweiten Teil der Abfrage, innerhalb des OBJECTIVES, wird mit den entsprechenden Werten aus dem Ergebnis der vorherigen Abfrage ersetzt:
... <IODATA loginguid="[!guid_login!]" sessionkey="[!guid_login!]"> <PROJECT guid="[!guid_project!]" sessionkey="[!guid_login!]"> <EXPORTREPORT days="7" action="deleteall" deletelogfiles="1" /> </PROJECT> </IODATA> </OBJECTIVES> </RQLCOMMAND>
...
<IODATA loginguid="E1B3501F8E3C48FB91521EA0A4011FC5" sessionkey="E1B3501F8E3C48FB91521EA0A4011FC5"> <PROJECT guid="1686D0DD0E674602B47EF55689A7085F" sessionkey="E1B3501F8E3C48FB91521EA0A4011FC5"> <EXPORTREPORT days="7" action="deleteall" deletelogfiles="1" /> </PROJECT> </IODATA>
RESPONSE-004:
<IODATA>
<EXPORTREPORT days="7"
action="deleteall"
deletelogfiles="1"
languagevariantid="DEU"
dialoglanguageid="DEU"
projectguid="1686D0DD0E674602B47EF55689A7085F" />
</IODATA>
Hinweis: Die for-Schleife lässt sich auch beliebig tief verschachteln, sofern es Sinn macht und auch Ergbnisse zurückgeliefert werden. Die Syntax sieht dann wie folgt aus:
<LOGIN-RQL /> <RQLCOMMAND type="for" name="Name des Objekts, das die Ergebnisliste enthält."> <LIST> <!-- Ersetzung der nachfolgenden Platzhalter aus Ergebnis von LOGIN-RQL --> <!-- RQL1, das die Ergebnismenge zurückgibt. --> </LIST> <OBJECTIVES> <RQLCOMMAND type="for" name="Name des Objekts, das die Ergebnisliste enthält."> <LIST> <!-- Ersetzung der nachfolgenden Platzhalter aus Ergebnis von LOGIN-RQL + RQL1 --> <!-- RQL2, das die Ergebnismenge zurückgibt. --> </LIST> <OBJECTIVES> <RQLCOMMAND type="for" name="Name des Objekts, das die Ergebnisliste enthält."> <LIST> <!-- Ersetzung der nachfolgenden Platzhalter aus Ergebnis von LOGIN-RQL + RQL1 + RQL2 --> <!-- RQL3, das die Ergebnismenge zurückgibt. --> </LIST> <OBJECTIVES> <!-- Ersetzung der nachfolgenden Platzhalter aus Ergebnis von LOGIN-RQL + RQL1 + RQL2 + RQL3 --> <!-- RQL4, die für jedes Ergebnis verwendet werden. --> </OBJECTIVES> </RQLCOMMAND> </OBJECTIVES> </RQLCOMMAND> </OBJECTIVES> </RQLCOMMAND>
Mit der Kontrollstruktur for-Schleife lassen sich die Ergebnisse entsprechend gut verarbeiten und auch hier ist die Ersetzungslogik der Platzhalter eine hilfreiche Unterstützung.
Im nächsten Artikel RQL-Befehle in benutzerdefinierten Aufträgen: if-Anweisung aus dieser Themenserie, werden wir uns die zweite Kontrollstruktur genauer ansehen.
Bis dahin, viel Spaß beim stöbern ;)
... ist Senior Site Reliability Engineer bei der Vodafone GmbH in Düsseldorf. Seit dem Jahr 2007 betreut er zusammen mit seinen Kollegen die OpenText- (vormals RedDot-) Plattform Web Site Management für die deutsche Konzernzentrale.
Er entwickelt Erweiterungen in Form von Plug-Ins und PowerShell Skripten. Seit den Anfängen in 2001 (RedDot CMS 4.0) kennt er sich speziell mit der Arbeitweise und den Funktionen des Management Server aus.