Clarity PPM

Expand all | Collapse all

<Gel:Parse: var inside another <gel:parse> variable

Jump to Best Answer
  • 1.  <Gel:Parse: var inside another <gel:parse> variable

    Posted 04-07-2016 09:16 AM

    Hi All,

     

    I'd like to ask if someone of you, working with GEL, used <gel:parse> inside next <gel:parse> variable . I didn't find it anywhere but I think it should work.

    If not please notify me and suggest another solution. Many Thanks

     

    In this example I'm trying to "re-use" a piece of code where Cost or Budget plan is retrieved. I've put this code into $xogReadFinPlan_Query variable and would like to "add" this variable/XML code into $xogReadFinPlan - the whole XOG read for Cost or Budget plan read according to $Plan_type. I assume a "select" statement there is maybe not correct

    but couldn't find out what should be there. Can you please help if anyone knows this? Thanks og

    I assume a "select" statement

    ReadFinPlan_Query$xogReadFinPlan_Query

    <!-- Prepare XOG Fin plan read according to Fin plan type, 
      if FORECAST then Cost plan if BUDGET, then Budget plan-->
      <gel:parse var="xogReadFinPlan_Query">
      <Query>
      <Filter name="code" criteria="EQUALS">${Plan_code}</Filter>
      <Filter name="investmentCode" criteria="EQUALS">${Project_code}</Filter>
      </Query>
      </gel:parse>
    
      <core:if test="${debugFlag != 0}">
      <gel:set asString="true" select="$xogReadFinPlan_Query" var="output"/>
      <core:set value="xogReadFinPlan_Query read: ${output}" var="logMessage"/>
      <gel:log level="DEBUG">${logMessage}</gel:log>
      </core:if>
      <gel:out></gel:out>
    
      <!-- Budget plan XOG read -->
      <core:if test="${Plan_type eq 'BUDGET'}">
      <gel:parse var="xogReadFinPlan">
      <NikuDataBus xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../xsd/nikuxog_budgetPlan.xsd"> 
      <Header version="13.3.0.286" action="read" objectType="budgetPlan" externalSource="NIKU">
      <args name="no_dependencies" value="true"/>
      </Header>
      <gel:set select="$xogReadFinPlan/NikuDataBus" value="${xogReadFinPlan_Query}" insert="true"/>
      </NikuDataBus>
      </gel:parse>
      </core:if>
    
      <!-- Cost plan XOG read -->
      <core:if test="${Plan_type eq 'FORECAST'}">
      <gel:parse var="xogReadFinPlan">
      <NikuDataBus xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../xsd/nikuxog_costPlan.xsd"> 
      <Header version="13.3.0.286" action="read" objectType="costPlan" externalSource="NIKU">
      <args name="no_dependencies" value="true"/>
      </Header>
      <gel:set select="$xogReadFinPlan/NikuDataBus"  value="${xogReadFinPlan_Query}" insert="true"/>
      </NikuDataBus>
      </gel:parse>
      </core:if>
    

     

     

    Edit: And the error is saying" Missing or invalid XML" ... as usual

    err.JPG

    Matej



  • 2.  Re: <Gel:Parse: var inside another <gel:parse> variable
    Best Answer

    Posted 04-07-2016 09:28 AM

    there are other ways (XPATH) of handling this, but I think just using <gel:include> where you have that inner

    <gel:set select="$xogReadFinPlan/NikuDataBus" value="${xogReadFinPlan_Query}" insert="true"/>

    would be what you want.

     

    i.e.

    <gel:include select="$xogReadFinPlan_Query" />

    (in place of that line above)

     

    (EDIT:just corrected syntax)



  • 3.  Re: <Gel:Parse: var inside another <gel:parse> variable

    Posted 04-07-2016 10:03 AM

    Hi Dave,

     

    Works perfectly ... just with one note, correctly it should be <gel:include select="$xogReadFinPlan_Query" />

    So just without brackets {}....

     

    Now continuously working because got another error (on the next lines, similar but, huger parse), but it's something differently....

     

    ERROR: <gel:parse> The markup in the document following the root element must be well-formed.

     

    Thanks again



  • 4.  Re: <Gel:Parse: var inside another <gel:parse> variable

    Posted 04-07-2016 11:20 AM

    Just another approach which I have used in the past.

     

    <?xml version="1.0" encoding="utf-8"?>
    <gel:script
        xmlns:core="jelly:core"
        xmlns:log="jelly:log"
        xmlns:gel="jelly:com.niku.union.gel.GELTagLibrary"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    
        <!-- test values -->
        <core:set var="Plan_code" value="PlanCode1234" />
        <core:set var="Project_code" value="ProjectCode987" />
        <core:set var="Plan_type" value="BUDGET" />
    
        <!-- Main xog template -->
        <core:set var="xogReadFinPlanString" value="&lt;NikuDataBus xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:noNamespaceSchemaLocation='../xsd/nikuxog_costPlan.xsd'&gt;   
                    &lt;Header version='13.3.0.286' action='read' objectType='costPlan' externalSource='NIKU'&gt;&lt;args name='no_dependencies' value='true'/&gt;&lt;/Header&gt;  
                    &lt;Query&gt;  
                        &lt;Filter name='code' criteria='EQUALS'&gt;${Plan_code}&lt;/Filter&gt;  
                        &lt;Filter name='investmentCode' criteria='EQUALS'&gt;${Project_code}&lt;/Filter&gt;  
                    &lt;/Query&gt;  
                &lt;/NikuDataBus&gt;" />
        <gel:log>xogReadFinPlanString before Replacement</gel:log>
        <gel:log>${xogReadFinPlanString}"</gel:log>
    
        <!-- Replace the costPlan for budgetPlan -->
        <core:if test="${Plan_type eq 'BUDGET'}">
            <core:set  var="xogReadFinPlanString" value='${xogReadFinPlanString.replaceAll("costPlan", "budgetPlan")}' />
        </core:if>
        <gel:log>xogReadFinPlanString after Replacement</gel:log>
        <gel:log>${xogReadFinPlanString}"</gel:log>
    
        <!-- Convert the stringi into something we can use for XOG -->
        <core:new var="inputStreamReader" className="java.io.ByteArrayInputStream" >
            <core:arg value="${xogReadFinPlanString.getBytes()}" />
        </core:new>
        <gel:parse var="xogReadFinPlan" file="${inputStreamReader}" />
        <gel:serialize fileName="xogReadFinPlan.xml" var="${xogReadFinPlan}"/>
    
    </gel:script>
    

     

     

    V/r,

    Gene



  • 5.  Re: <Gel:Parse: var inside another <gel:parse> variable

    Posted 04-08-2016 03:53 AM

    Hi Gene,

     

    thanks for posting your hints also, but Dave's tip is fine for XOG read Cost and Budget plans.

    Unfortunately that I cannot say about XOG write

     

    I have the same logic steps for XOG write (1. parse var ($xogWriteFinPlan_Details) for Fin plan details, 2. parse var ($xogWriteFinPlan) for

    the whole XOG write XML file), but it throws me above error:

    (ERROR: <gel:parse> The markup in the document following the root element must be well-formed.)

    It has to be said, when it's just in one parse var - like before (just w.g. for Cost plan), it works fine....

     

    So now it's very strange for me where this error comes from...

     

    1. Parse var for Fin plan details - Here is the simplified code, because it's too long, but for understanding this should be enough....

    <!-- We set Details for Fin plans into parse variable first to be able to put it into the whole XML file -->
      <gel:parse var="xogWriteFinPlan_Details">
            <GroupingAttributes>
                <GroupingAttribute>cost_type_id</GroupingAttribute>
                <GroupingAttribute>transaction_class_id</GroupingAttribute>
            </GroupingAttributes>
            <Details>
                  <!-- Fill in variables for Fin plan from SQL query above -->
                  <core:forEach items="${Fin_plan_rows.rows}" trim="false" var="row_type">
                          <!-- Fill in detail of one row (Revenue and Actuals) into Fin plan  -->
                          <Detail>
                              <Cost>
                                      <core:forEach items="${Fin_plan_values.rows}" trim="false" var="row_value">
                                          <!-- some values there.... -->
                                  </core:forEach>
                              </Cost>
                              <Units>
                                        <core:forEach items="${Fin_plan_values.rows}" trim="false" var="row_value">
                                              <!-- some values there.... -->
                                        </core:forEach>
                              </Units>
                              <Revenue>
                                      <core:forEach items="${Fin_plan_values.rows}" trim="false" var="row_value">
                                                  <!-- some values there.... -->
                                          </core:forEach>
                              </Revenue>
                            <GroupingAttributes>
                                        <GroupingAttribute code="cost_type_id" value="${Cost_type}"/>
                                        <GroupingAttribute code="transaction_class_id" value="${Transaction_class}"/>
                            </GroupingAttributes>
                            <CustomInformation>
                                          <ColumnValue name="partition_code">NIKU.ROOT</ColumnValue>
                            </CustomInformation>
                      </Detail>
                  </core:forEach>
            </Details>
            <CustomInformation>
                            <ColumnValue name="partition_code">NIKU.ROOT</ColumnValue>
                            <ColumnValue name="z_checkbox_approved">true</ColumnValue>
                            <ColumnValue name="z_checkbox_rejected">false</ColumnValue>
                            <ColumnValue name="z_checkbox_submitted">true</ColumnValue>
              </CustomInformation>
      </gel:parse>
    

     

    2. Parse var - The whole XOG write XML doc for Budget plan:

    <!-- Whole XML: XOG write for Budget plan -->
      <core:if test="${Plan_type eq 'BUDGET'}">
           <gel:parse var="xogWriteFinPlan">
                 <NikuDataBus xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../xsd/nikuxog_budgetPlan.xsd">
                      <Header action="write" externalSource="NIKU" objectType="budgetPlan" version="13.3.0.286"/>
                          <BudgetPlans>
                                 <BudgetPlan benefitPlanCode="" code="Kill/Close_${Plan_code}" finishPeriod="${End_period}" 
                                             forceReplace="true" investmentCode="${Project_code}"
                                             investmentType="project" name="Kill/Close" periodType="ANNUALLY" revision="1"
                                             startPeriod="${Start_period}" sourceCostPlanCode="${Plan_code}" status="APPROVED">
                                   <Description/>
                                            <!-- Fin plan details included there !!! -->
                                           <gel:include select="$xogWriteFinPlan_Details"/>
                                </BudgetPlan>
                          </BudgetPlans>
                 </NikuDataBus>
         </gel:parse>
    </core:if>
    

     

    Matej



  • 6.  Re: <Gel:Parse: var inside another <gel:parse> variable

    Posted 04-08-2016 04:24 AM

    I don't know what the proper terminology for this is, but I suspect that message is appearing because your xogWriteFinPlan_Details is not all part of a 'single tag'  - whether you fix this by specifying the xmlns in there, or you could split it up into 3 chunks (since it contains 3 outer 'tag's ; GroupingAttributes/Details/CustomInformation) ?????



  • 7.  Re: <Gel:Parse: var inside another <gel:parse> variable

    Posted 04-08-2016 04:45 AM

    Hi Dave,

     

    Exactly, You are right again! The root-cause is that the <Gel:parse> variable cannot contain more than 1 "high" tag. In my case they were 3 as you mentioned (GroupingAttributes/Details/CustomInformation). Deleting 2 of them, so just <Details> remained in parse var, solved it Thanks for this valuable help... I think this is quite important "hint", not sure if it's written anywhere...

     

    Thanks also to Gene for his script showing the second way of "re-using" code....

     

    So my final script looks something like:

     

    1. Parse var for Fin plan details

    <!-- We set Details for Fin plans into parse variable first to be able to put it into the whole XML file -->  
      <gel:parse var="xogWriteFinPlan_Details">  
            <Details>  
                            <!-- Just all details there... -->
            </Details>  
      </gel:parse>  
    

     

    2. Parse var - The whole XOG write XML doc for Budget plan:

    <core:if test="${Plan_type eq 'BUDGET'}"> 
          <gel:parse var="xogWriteFinPlan"> 
                <NikuDataBus xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../xsd/nikuxog_budgetPlan.xsd"> 
                      <Header action="write" externalSource="NIKU" objectType="budgetPlan" version="13.3.0.286"/> 
                          <BudgetPlans> 
                                <BudgetPlan benefitPlanCode="" code="Kill/Close_${Plan_code}" finishPeriod="${End_period}" 
                                            forceReplace="true" investmentCode="${Project_code}" 
                                            investmentType="project" name="Kill/Close" periodType="ANNUALLY" revision="1" 
                                            startPeriod="${Start_period}" sourceCostPlanCode="${Plan_code}" status="APPROVED"> 
                                  <Description/> 
                                          <GroupingAttributes>
                                                    <GroupingAttribute>cost_type_id</GroupingAttribute>
                                                    <GroupingAttribute>transaction_class_id</GroupingAttribute>
                                        </GroupingAttributes>
                                                  <!-- Fin plan details included there !!! -->
                                                  <gel:include select="$xogWriteFinPlan_Details"/>
                                        <CustomInformation>
                                                  <ColumnValue name="partition_code">NIKU.ROOT</ColumnValue>
                                                  <ColumnValue name="z_checkbox_approved">true</ColumnValue>
                                                  <ColumnValue name="z_checkbox_rejected">false</ColumnValue>
                                                  <ColumnValue name="z_checkbox_submitted">true</ColumnValue>
                                        </CustomInformation>
                                </BudgetPlan> 
                          </BudgetPlans> 
                </NikuDataBus> 
        </gel:parse> 
    </core:if> 
    

     

    Matej