Jelajahi Sumber

HPCC-16245 Support ESPlist in esdl

Also fix a bug for retrieving primitive array input

Signed-off-by: wangkx <kevin.wang@lexisnexis.com>
wangkx 8 tahun lalu
induk
melakukan
be40fa3b6a

+ 13 - 5
esp/esdllib/esdl_def.cpp

@@ -515,12 +515,13 @@ class EsdlDefArray : public EsdlDefObject, implements IEsdlDefArray
 {
 private:
     Owned<IProperties> recSelectors;
+    bool isEsdlList;
 
 public:
     IMPLEMENT_IINTERFACE;
     IMPLEMENT_ESDL_DEFOBJ;
 
-    EsdlDefArray(StartTag &tag, EsdlDefinition *esdl) : EsdlDefObject(tag, esdl){}
+    EsdlDefArray(StartTag &tag, EsdlDefinition *esdl, const bool _isEsdlList) : EsdlDefObject(tag, esdl), isEsdlList(_isEsdlList){}
     virtual EsdlDefTypeId getEsdlType(){return EsdlTypeArray;}
 
     void load(XmlPullParser *xpp, StartTag &struct_tag)
@@ -534,7 +535,10 @@ public:
         {
             if( this->checkOptional(opts) )
             {
-                xml.append("<EsdlArray ");
+                if (isEsdlList)
+                    xml.append("<EsdlList ");
+                else
+                    xml.append("<EsdlArray ");
                 toXMLAttributes(xml);
                 xml.append("/>");
             }
@@ -554,6 +558,8 @@ public:
 
         return recSelectors.get();
     }
+
+    inline const bool checkIsEsdlList() { return isEsdlList; };
 };
 
 class EsdlDefAttribute : public EsdlDefObject, implements IEsdlDefAttribute
@@ -815,9 +821,9 @@ public:
         et->load(xpp, tag);
     }
 
-    void loadArray(EsdlDefinition *esdl, XmlPullParser *xpp, StartTag &tag)
+    void loadArray(EsdlDefinition *esdl, XmlPullParser *xpp, StartTag &tag, const bool isEsdlList)
     {
-        EsdlDefArray *art = new EsdlDefArray(tag, esdl);
+        EsdlDefArray *art = new EsdlDefArray(tag, esdl, isEsdlList);
         children.append(*dynamic_cast<IEsdlDefObject*>(art));
         art->load(xpp, tag);
     }
@@ -919,7 +925,9 @@ void EsdlDefStruct::load(EsdlDefinition *esdl, XmlPullParser *xpp, StartTag &str
                 else if(!stricmp(localname, "EsdlEnum"))
                     loadEnumRef(esdl, xpp, stag);
                 else if(!stricmp(localname, "EsdlArray"))
-                    loadArray(esdl, xpp, stag);
+                    loadArray(esdl, xpp, stag, false);
+                else if(!stricmp(localname, "EsdlList"))
+                    loadArray(esdl, xpp, stag, true);
                 else if(!stricmp(localname, "EsdlAttribute"))
                     loadAttribute(esdl, xpp, stag);
                 else

+ 1 - 0
esp/esdllib/esdl_def.hpp

@@ -114,6 +114,7 @@ interface IEsdlDefElement : extends IEsdlDefObject
 interface IEsdlDefArray : extends IEsdlDefObject
 {
     virtual IProperties *queryRecSelectors()=0;
+    virtual const bool checkIsEsdlList()=0;
 };
 
 interface IEsdlDefEnumDef : extends IEsdlDefObject

+ 111 - 1
esp/esdllib/esdl_transformer2.cpp

@@ -631,6 +631,9 @@ Esdl2Array::Esdl2Array(Esdl2Transformer *xformer, IEsdlDefObject *def) : Esdl2Ba
     type_unknown=false;
     inited=false;
 
+    IEsdlDefArray* defArray = dynamic_cast<IEsdlDefArray*>(def);
+    isEsdlList = defArray->checkIsEsdlList();
+
     const char *atype = def->queryProp("type");
     if (atype)
     {
@@ -700,6 +703,18 @@ void Esdl2Array::process(Esdl2TransformerContext &ctx, IPropertyTree *pt, const
         if (ctx.writer->length() != curlen && count)
             ctx.counter++;
     }
+    else if (isEsdlList)
+    {
+        int curlen = ctx.writer->length();
+        const char *tagname = queryOutputName(ctx);
+        if (esdl_type)
+            esdl_type->process(ctx, pt, tagname, NULL, count_output);
+        else
+            output_content(ctx, pt, tagname);
+
+        if (ctx.writer->length() != curlen && count)
+            ctx.counter++;
+    }
     else
     {
         const char *tagname = queryOutputName(ctx);
@@ -773,6 +788,18 @@ void Esdl2Array::process(Esdl2TransformerContext &ctx, const char *out_name, Esd
         if (ctx.writer->length() != curlen && count)
             ctx.counter++;
     }
+    else if (isEsdlList)
+    {
+        int curlen = ctx.writer->length();
+        const char *tagname = queryOutputName(ctx);
+        if (esdl_type)
+            esdl_type->process(ctx, tagname, NULL, count_output);
+        else
+            output_content(ctx, tagname);
+
+        if (ctx.writer->length() != curlen && count)
+            ctx.counter++;
+    }
     else
     {
         Owned<IInterface> prevLocation = ctx.writer->saveLocation();
@@ -895,7 +922,53 @@ void Esdl2Struct::process(Esdl2TransformerContext &ctx, IPropertyTree *pt, const
             {
                 const char *tagname = child.queryInputName(ctx);
                 if (pt->hasProp(tagname)||child.hasDefaults())
-                    child.process(ctx, pt->queryPropTree(tagname), child.queryOutputName(ctx), &local, count);
+                {
+                    unsigned numChildren = pt->getCount(tagname);
+                    bool isEsdlList = false;
+                    IEsdlDefObject*  def = child.queryEsdlDefObject();
+                    if (def->getEsdlType() == EsdlTypeArray)
+                    {
+                        IEsdlDefArray* defArray = dynamic_cast<IEsdlDefArray*>(def);
+                        isEsdlList = defArray->checkIsEsdlList();
+                    }
+                    if (!isEsdlList)
+                    {
+                        if (numChildren < 2)
+                            child.process(ctx, pt->queryPropTree(tagname), child.queryOutputName(ctx), &local, count);
+                        else
+                        {
+                            Owned<IPropertyTreeIterator> iter = pt->getElements(tagname);
+                            ForEach(*iter)
+                                child.process(ctx, &iter->query(), child.queryOutputName(ctx), &local, count);
+                        }
+                    }
+                    else
+                    {
+                        Owned<IInterface> prevLocation = ctx.writer->saveLocation();
+                        ctx.writer->outputBeginArray(tagname);
+                        int curlen = ctx.writer->length();
+
+                        if (numChildren < 2)
+                            child.process(ctx, pt->queryPropTree(tagname), child.queryOutputName(ctx), &local, count);
+                        else
+                        {
+                            Owned<IPropertyTreeIterator> iter = pt->getElements(tagname);
+                            ForEach(*iter)
+                                child.process(ctx, &iter->query(), child.queryOutputName(ctx), &local, count);
+                        }
+                        if (ctx.writer->length()==curlen) //nothing was added... empty content remove opening tag
+                        {
+                            ///ctx.writer->outputEndArray(tagname);
+                            ctx.writer->rewindTo(prevLocation); //rewind
+                        }
+                        else
+                        {
+                            ctx.writer->outputEndArray(tagname);
+                            if (count)
+                                ctx.counter++;
+                        }
+                    }
+                }
             }
         }
 
@@ -955,6 +1028,8 @@ void Esdl2Struct::process(Esdl2TransformerContext &ctx, const char *out_name, Es
             }
         }
 
+        StringBuffer esdlListName;
+        unsigned esdlListItemCount = 0;
         Esdl2LocalContext local;
         StringBuffer completeContent;
         for (int type=ctx.xppp->next(); type!=XmlPullParser::END_TAG; type=ctx.xppp->next())
@@ -1013,6 +1088,34 @@ void Esdl2Struct::process(Esdl2TransformerContext &ctx, const char *out_name, Es
                             Owned<IInterface> location = ctx.writer->saveLocation();
                             local.dataForProcessed = false;
 
+                            const char* tagName = child_start.getLocalName();
+                            if (!esdlListName.isEmpty())
+                            {
+                                if (streq(tagName, esdlListName.str()))
+                                    esdlListItemCount++;
+                                else
+                                { //A different esdl tag is coming. We need to close the last EsdlList.
+                                    ctx.writer->outputEndArray(esdlListName.str());
+                                    esdlListName.clear();
+                                    esdlListItemCount = 0;
+                                    location.setown(ctx.writer->saveLocation());
+                                }
+                            }
+
+                            if (esdlListName.isEmpty())
+                            {
+                                IEsdlDefObject*  def = child->queryEsdlDefObject();
+                                if (def->getEsdlType() == EsdlTypeArray)
+                                {
+                                    IEsdlDefArray* defArray = dynamic_cast<IEsdlDefArray*>(def);
+                                    if (defArray->checkIsEsdlList())
+                                    {
+                                        ctx.writer->outputBeginArray(tagName);
+                                        esdlListName.set(tagName);
+                                        esdlListItemCount++;
+                                    }
+                                }
+                            }
                             chd.process(ctx, NULL, &local);
 
                             if (local.dataForProcessed)
@@ -1024,6 +1127,11 @@ void Esdl2Struct::process(Esdl2TransformerContext &ctx, const char *out_name, Es
                                     ESDL_DBG("Taking out data for DataFor '%s' from out buffer", chd.queryDataFor()->queryName());
                                     local.setDataFor(chd.queryDataFor()->queryName(), ctx.writer->str()+len);
                                     ctx.writer->rewindTo(location);
+                                    if (esdlListItemCount == 1)
+                                    {// Not call outputEndArray()
+                                        esdlListName.clear();
+                                        esdlListItemCount = 0;
+                                    }
                                 }
                             }
 
@@ -1043,6 +1151,8 @@ void Esdl2Struct::process(Esdl2TransformerContext &ctx, const char *out_name, Es
                 }
             }
         }
+        if (!esdlListName.isEmpty())
+            ctx.writer->outputEndArray(esdlListName.str());
 
         if (completeContent.length()>0)
             ctx.writer->outputUtf8(rtlUtf8Length(completeContent.length(),completeContent.str()),completeContent.str(),NULL);

+ 2 - 0
esp/esdllib/esdl_transformer2.ipp

@@ -310,6 +310,8 @@ class Esdl2Array : public Esdl2Base
 
     bool inited;
     bool type_unknown;
+    bool isEsdlList;
+
 public:
     Esdl2Array(Esdl2Transformer *xformer, IEsdlDefObject *def);
     virtual ~Esdl2Array(){}

+ 30 - 10
esp/esdllib/params2xml.cpp

@@ -143,6 +143,8 @@ void child2xml(IEsdlDefinition *esdl, IEsdlDefObject &child, StringBuffer &flexp
                     item_tag = "item";
                 const char *artype = child.queryProp("type");
                 IEsdlDefStruct *cst = esdl->queryStruct(artype);
+                IEsdlDefArray* defArray = dynamic_cast<IEsdlDefArray*>(&child);
+                bool isEsdlList = defArray->checkIsEsdlList();
 
                 flexpath.append(name);
 
@@ -158,7 +160,10 @@ void child2xml(IEsdlDefinition *esdl, IEsdlDefObject &child, StringBuffer &flexp
                     int itemcount = (countstr) ? atoi(countstr) : 0;
                     if (itemcount)
                     {
-                        xmlstr.append('<').append(name).append('>');
+                        if (isEsdlList)
+                            item_tag = name;
+                        else
+                            xmlstr.append('<').append(name).append('>');
                         unsigned arxml_setpoint = xmlstr.length();
                         for (int pos = 0; pos < itemcount; pos++)
                         {
@@ -166,10 +171,13 @@ void child2xml(IEsdlDefinition *esdl, IEsdlDefObject &child, StringBuffer &flexp
                             paramsStruct2xml(esdl, cst, item_tag, params, xmlstr, flexpath, flags, ver, false);
                             flexpath.setLength(arpath_setpoint);
                         }
-                        if (xmlstr.length()>arxml_setpoint)
-                            xmlstr.append("</").append(name).append('>');
-                        else
-                            xmlstr.setLength(arxml_setpoint - strlen(name) - 2);
+                        if (!isEsdlList)
+                        {
+                            if (xmlstr.length()>arxml_setpoint)
+                                xmlstr.append("</").append(name).append('>');
+                            else
+                                xmlstr.setLength(arxml_setpoint - strlen(name) - 2);
+                        }
                     }
                 }
                 else
@@ -177,7 +185,10 @@ void child2xml(IEsdlDefinition *esdl, IEsdlDefObject &child, StringBuffer &flexp
                     const char *val = params->queryProp(flexpath.str());
                     if (val && *val)
                     {
-                        xmlstr.append('<').append(name).append('>');
+                        if (isEsdlList)
+                            item_tag = name;
+                        else
+                            xmlstr.append('<').append(name).append('>');
                         unsigned arxml_setpoint = xmlstr.length();
                         StringBuffer itemval;
                         for (const char *finger=val; *finger; finger++)
@@ -195,10 +206,19 @@ void child2xml(IEsdlDefinition *esdl, IEsdlDefObject &child, StringBuffer &flexp
                             else
                                 itemval.append(*finger);
                         }
-                        if (xmlstr.length()>arxml_setpoint)
-                            xmlstr.append("</").append(name).append('>');
-                        else
-                            xmlstr.setLength(arxml_setpoint - strlen(name) - 2);
+                        if (!itemval.isEmpty()) //Last item has not been added yet!
+                        {
+                            xmlstr.append('<').append(item_tag).append('>');
+                            encodeUtf8XML(itemval.str(), xmlstr);
+                            xmlstr.append("</").append(item_tag).append('>');
+                        }
+                        if (!isEsdlList)
+                        {
+                            if (xmlstr.length()>arxml_setpoint)
+                                xmlstr.append("</").append(name).append('>');
+                            else
+                                xmlstr.setLength(arxml_setpoint - strlen(name) - 2);
+                        }
                     }
                 }
                 flexpath.setLength(flexpath_setpoint);

+ 30 - 9
esp/xslt/esdl2ecl.xslt

@@ -107,11 +107,17 @@ end;
 <xsl:text disable-output-escaping="yes">
 </xsl:text>
 	</xsl:template>
-	<xsl:template match="EsdlArray[@type='string']">
+	<xsl:template match="EsdlArray[@type='string']|EsdlList[@type='string']">
 		<xsl:if test="not(@ecl_hide) and (@ecl_keep or not(@get_data_from))">
 		<xsl:text disable-output-escaping="yes">	set of string </xsl:text><xsl:call-template name="output_ecl_name"/>
 		<xsl:text disable-output-escaping="yes"> {xpath('</xsl:text>
-		<xsl:if test="not(@flat_array)"><xsl:value-of select="@name"/></xsl:if><xsl:text disable-output-escaping="yes">/</xsl:text><xsl:call-template name="output_item_tag"/><xsl:text disable-output-escaping="yes">')</xsl:text>
+		<xsl:choose>
+			<xsl:when test="name(.) ='EsdlArray'">
+				<xsl:if test="not(@flat_array)"><xsl:value-of select="@name"/></xsl:if><xsl:text disable-output-escaping="yes">/</xsl:text><xsl:call-template name="output_item_tag"/>
+			</xsl:when>
+			<xsl:otherwise><xsl:value-of select="@name"/></xsl:otherwise>
+		</xsl:choose>
+                <xsl:text disable-output-escaping="yes">')</xsl:text>
 		<xsl:choose>
 			<xsl:when test="@max_count_var"><xsl:text disable-output-escaping="yes">, MAXCOUNT(</xsl:text><xsl:value-of select="@max_count_var"/><xsl:text disable-output-escaping="yes">)</xsl:text></xsl:when>
 			<xsl:when test="@max_count"><xsl:text disable-output-escaping="yes">, MAXCOUNT(</xsl:text><xsl:value-of select="@max_count"/><xsl:text disable-output-escaping="yes">)</xsl:text></xsl:when>
@@ -132,11 +138,19 @@ end;
 		  <xsl:text disable-output-escaping="yes">&#xa;</xsl:text>
         </xsl:if>
 	</xsl:template>
-	<xsl:template match="EsdlArray">
+	<xsl:template match="EsdlArray|EsdlList">
 		<xsl:if test="not(@ecl_hide) and (@ecl_keep or not(@get_data_from))">
 			<xsl:text disable-output-escaping="yes">	dataset(</xsl:text> <xsl:call-template name="output_ecl_array_type"/><xsl:text disable-output-escaping="yes">) </xsl:text><xsl:call-template name="output_ecl_name"/>
-            <xsl:text disable-output-escaping="yes"> {xpath('</xsl:text>
-			<xsl:if test="not(@flat_array)"><xsl:value-of select="@name"/></xsl:if><xsl:text disable-output-escaping="yes">/</xsl:text><xsl:call-template name="output_item_tag"/><xsl:text disable-output-escaping="yes">')</xsl:text>
+            		<xsl:text disable-output-escaping="yes"> {xpath('</xsl:text>
+			<xsl:choose>
+				<xsl:when test="name(.) ='EsdlArray'">
+ 					<xsl:if test="not(@flat_array)"><xsl:value-of select="@name"/></xsl:if>
+					<xsl:text disable-output-escaping="yes">/</xsl:text>
+					<xsl:call-template name="output_item_tag"/>
+                                </xsl:when>
+                        	<xsl:otherwise><xsl:value-of select="@name"/></xsl:otherwise>
+			</xsl:choose>
+            		<xsl:text disable-output-escaping="yes">')</xsl:text>
 			<xsl:choose>
 				<xsl:when test="@max_count_var"><xsl:text disable-output-escaping="yes">, MAXCOUNT(</xsl:text><xsl:value-of select="@max_count_var"/><xsl:text disable-output-escaping="yes">)</xsl:text></xsl:when>
 				<xsl:when test="@max_count"><xsl:text disable-output-escaping="yes">, MAXCOUNT(</xsl:text><xsl:value-of select="@max_count"/><xsl:text disable-output-escaping="yes">)</xsl:text></xsl:when>
@@ -296,16 +310,23 @@ end;
 	</xsl:if>
 	<xsl:if test="@ecl_type and (@type or @complex_type)">
         <xsl:choose>
-         <xsl:when test="name()='EsdlArray'">
+         <xsl:when test="name()='EsdlArray|EsdlList'">
            <xsl:text disable-output-escaping="yes"> // Real type: </xsl:text>
            <xsl:text disable-output-escaping="yes">dataset(t_</xsl:text>
            <xsl:value-of select="@type"/>
            <xsl:text disable-output-escaping="yes">) </xsl:text>
            <xsl:call-template name="output_ecl_name"/>
            <xsl:text disable-output-escaping="yes"> {xpath('</xsl:text>
-           <xsl:value-of select="@name"/>
-           <xsl:text disable-output-escaping="yes">/</xsl:text>
-           <xsl:call-template name="output_item_tag"/>
+           <xsl:choose>
+		<xsl:when test="name() ='EsdlArray'">
+                  <xsl:if test="not(@flat_array)"><xsl:value-of select="@name"/></xsl:if>
+                  <xsl:text disable-output-escaping="yes">/</xsl:text>
+                  <xsl:call-template name="output_item_tag"/>
+                </xsl:when>
+		<xsl:otherwise>
+                  <xsl:value-of select="@name"/>
+	        </xsl:otherwise>
+             </xsl:choose>
            <xsl:text disable-output-escaping="yes">')};</xsl:text>
          </xsl:when>
          <xsl:when test="name()='EsdlElement' and starts-with(@ecl_type,'tns:')">

+ 13 - 2
esp/xslt/esxdl2xsd.xslt

@@ -320,12 +320,23 @@
             </xsl:otherwise>
         </xsl:choose>
     </xsl:template>
+    <xsl:template match="EsdlList">
+        <xsd:element minOccurs="0" maxOccurs="unbounded">
+            <xsl:attribute name="name"><xsl:value-of select="@name"/></xsl:attribute>
+	    <xsl:attribute name="type">
+            	<xsl:choose>
+                    <xsl:when test="@type='string'">xsd:string</xsl:when>
+                    <xsl:otherwise>tns:<xsl:value-of select="@type"/></xsl:otherwise>
+            	</xsl:choose>
+	    </xsl:attribute>
+	</xsd:element>
+    </xsl:template>
     <xsl:template match="EsdlRequest">
         <xsd:element>
             <xsl:attribute name="name"><xsl:value-of select="@name"/></xsl:attribute>
             <xsd:complexType>
                 <xsd:all>
-                    <xsl:apply-templates select="EsdlElement|EsdlArray|EsdlEnum"/>
+                    <xsl:apply-templates select="EsdlElement|EsdlArray|EsdlList|EsdlEnum"/>
                 </xsd:all>
             </xsd:complexType>
         </xsd:element>
@@ -335,7 +346,7 @@
             <xsl:attribute name="name"><xsl:value-of select="@name"/></xsl:attribute>
             <xsd:complexType>
                 <xsd:all>
-                    <xsl:apply-templates select="EsdlElement|EsdlArray|EsdlEnum"/>
+                    <xsl:apply-templates select="EsdlElement|EsdlArray|EsdlList|EsdlEnum"/>
                 </xsd:all>
             </xsd:complexType>
         </xsd:element>

+ 54 - 0
esp/xslt/gen_form.xsl

@@ -536,6 +536,8 @@
                     <xsl:with-param name="fieldId" select="$fieldId"/>
                     <xsl:with-param name="value" select="$node/@default"/>
                     <xsl:with-param name="annot" select="$node/xsd:annotation/xsd:appinfo/form"/>
+                    <xsl:with-param name="name" select="$node/@name"/>
+                    <xsl:with-param name="maxOccurs" select="$node/@maxOccurs"/>
                 </xsl:call-template>
             </xsl:when>
             <xsl:when test="starts-with($type, 'tns:ArrayOf')">
@@ -594,6 +596,9 @@
             <xsl:when test="starts-with($type, 'tns:')">
                   <xsl:variable name="bareType" select="substring($type,5)"/>
                   <xsl:choose>
+                    <xsl:when test="$node/@maxOccurs='unbounded'">
+                        <xsl:value-of select="concat('&quot;+get_Array_Input(&quot;',$fieldId,'&quot;,&quot;',$bareType,'&quot;,&quot;',$node/@name,'&quot;)+&quot;')"/>
+		    </xsl:when>
                     <xsl:when test="$schemaRoot/xsd:complexType[@name=$bareType]/xsd:all/xsd:element">
                         <xsl:call-template name="GenEspStructHtmlTable">
                             <xsl:with-param name="nodes" select="($schemaRoot/xsd:complexType[@name=$bareType]/xsd:all/xsd:element) | ($schemaRoot/xsd:complexType[@name=$bareType]/xsd:attribute)"/>
@@ -982,9 +987,56 @@
         <xsl:param name="fieldId"/>
         <xsl:param name="value"/>
         <xsl:param name="annot"/>
+        <xsl:param name="name"/>
+        <xsl:param name="maxOccurs"/>
         <xsl:choose>
             <!-- string -->
             <xsl:when test="$typeName='string'">
+		<xsl:choose>
+			<xsl:when test="$maxOccurs='unbounded'">
+				<xsl:if test="$useTextareaForStringArray">
+					<xsl:variable name="inputRows">
+						<xsl:choose>
+							<xsl:when test="$annot/@formRows">
+								<xsl:value-of select="$annot/@formRows"/>
+							</xsl:when>
+							<xsl:otherwise>5</xsl:otherwise>
+						</xsl:choose>
+					</xsl:variable>
+					<xsl:variable name="inputCols">
+						<xsl:choose>
+							<xsl:when test="$annot/@formCols">
+								<xsl:value-of select="$annot/@formCols"/>
+							</xsl:when>
+							<xsl:otherwise>50</xsl:otherwise>
+						</xsl:choose>
+					</xsl:variable>
+					<xsl:text disable-output-escaping="yes"><![CDATA[<textarea name=']]></xsl:text>
+					<xsl:value-of select="$fieldId"/>
+					<xsl:text disable-output-escaping="yes"><![CDATA[' id=']]></xsl:text>
+					<xsl:value-of select="$fieldId"/>
+					<xsl:text disable-output-escaping="yes"><![CDATA[' cols=']]></xsl:text>
+					<xsl:value-of select="$inputCols"/>
+					<xsl:text disable-output-escaping="yes"><![CDATA[' rows=']]></xsl:text>
+					<xsl:value-of select="$inputRows"/>
+					<xsl:text disable-output-escaping="yes"><![CDATA[' >]]></xsl:text>
+					<xsl:if test="$set_ctrl_value">
+						<xsl:text disable-output-escaping="yes">esp string array value 1\nesp string array value 2</xsl:text>
+					</xsl:if>
+					<xsl:text disable-output-escaping="yes"><![CDATA[</textarea>]]></xsl:text>
+				</xsl:if>
+				<xsl:if test="not($useTextareaForStringArray)">
+					<!-- new way  -->
+					<xsl:text disable-output-escaping="yes"><![CDATA["+get_Array_Input("]]></xsl:text>
+					<xsl:value-of select="$fieldId"/>
+					<xsl:text disable-output-escaping="yes"><![CDATA[","]]></xsl:text>
+					<xsl:value-of select="'XsdArray'"/>
+					<xsl:text disable-output-escaping="yes"><![CDATA[","]]></xsl:text>
+					<xsl:value-of select="$name"/>
+					<xsl:text disable-output-escaping="yes"><![CDATA[")+"]]></xsl:text>
+				</xsl:if>
+			</xsl:when>
+			<xsl:otherwise>
                 <xsl:variable name="inputRows">
                     <xsl:choose>
                         <xsl:when test="$annot/@formRows">
@@ -1054,6 +1106,8 @@
                     </xsl:otherwise>
                     <!-- -->
                 </xsl:choose>
+                </xsl:otherwise>
+                </xsl:choose>
             </xsl:when>
             <!-- numbers -->
             <xsl:when test="$typeName='int' or $typeName='integer' or $typeName='short' or $typeName = 'long' or $typeName='unsignedInt' or $typeName='nonPositiveInteger' or $typeName='negative' or  $typeName='nonNegativeInteger' or $typeName='positiveInteger' or $typeName='imsignedShort' or $typeName='unsignedLong' or $typeName = 'long' or $typeName='byte' or $typeName='unsignedByte' or $typeName='double' or $typeName='float' ">

+ 12 - 3
tools/esdlcomp/esdlcomp.h

@@ -430,7 +430,7 @@ public:
 
     bool isEspArrayOf(const char *elem_type=NULL, bool def=true)
     {
-        if (flags & PF_TEMPLATE && !strcmp(templ, "ESParray"))
+        if (flags & PF_TEMPLATE && (!strcmp(templ, "ESParray") || streq(templ, "ESPlist")))
         {
             if (!elem_type || !typname)
                 return def;
@@ -441,14 +441,14 @@ public:
 
     bool isEspStringArray()
     {
-        if (flags & PF_TEMPLATE && !strcmp(templ, "ESParray"))
+        if (flags & PF_TEMPLATE && (!strcmp(templ, "ESParray") || streq(templ, "ESPlist")))
             return (!typname||!strcmp(typname, "string")||!strcmp(typname, "EspTextFile"));
         return false;
     }
 
     bool isPrimitiveArray()
     {
-        if (flags & PF_TEMPLATE && !strcmp(templ, "ESParray"))
+        if (flags & PF_TEMPLATE && (!strcmp(templ, "ESParray") || streq(templ, "ESPlist")))
             return (kind != TK_STRUCT && kind != TK_null && kind != TK_ESPENUM && kind != TK_ESPSTRUCT) || !typname;
         return false;
     }
@@ -562,6 +562,15 @@ public:
                 mtag->toStringXmlAttr(out);
             }
         }
+        else if (flags & PF_TEMPLATE && !strcmp(templ, "ESPlist"))
+        {
+            out.appendf("\t\t<EsdlList name='%s' ", name);
+            toStringXmlAttr(out);
+            for (MetaTagInfo *mtag=tags; mtag; mtag=mtag->next)
+            {
+                mtag->toStringXmlAttr(out);
+            }
+        }
         else if (kind==TK_ENUM)
         {
             out.appendf("\t\t<EsdlEnumItem name='%s'", name);

+ 44 - 1
tools/esdlcomp/esdlgram.y

@@ -96,6 +96,7 @@ int  nCommentStartLine = -1;
   ESPMETHODREF
   ESPVERSIONDEF
   ESPTEMPLATE
+  ESPTEMPLATELIST
   ESPMOUNT
   ESPUSES
   ESPDEFEXPORT
@@ -479,7 +480,49 @@ EspPropertyList
  ;
 
 EspPropertyDef
- : EspTemplateStart ESPTEMPLATE '<' EspTemplateParams '>' ID EspPropertyInit ';'
+ : EspTemplateStart ESPTEMPLATELIST '<' EspTemplateParams '>' ID EspPropertyInit ';'
+ {
+    if (CurParam)
+    {
+        if (CurParam->name && ((CurParam->flags & PF_RETURN)==0))
+        {
+            if (CurParam->kind==TK_null)
+            {
+                CurParam->kind = TK_STRUCT;
+                CurParam->typname = CurParam->name;
+            }
+            else
+            {
+                errnum = 9;
+                yyerror("unknown/unexpected ID");
+            }
+        }
+
+        CurParam->flags |= PF_TEMPLATE;
+        CurParam->templ = strdup($2.getName());
+        CurParam->name = strdup($6.getName());
+        CurParam->tags = getClearCurMetaTags();
+    }
+    else
+        CurMetaTags=NULL;
+    AddEspProperty();
+ }
+ | EspTemplateStart ESPTEMPLATELIST '<' EspType ID '>' ID ';'
+ {
+    if (CurParam)
+    {
+        CurParam->flags |= PF_TEMPLATE;
+        CurParam->templ = strdup($2.getName());
+        CurParam->name = strdup($5.getName());
+        CurParam->typname = CurParam->name;
+        CurParam->name = strdup($7.getName());
+        CurParam->tags = getClearCurMetaTags();
+    }
+    else
+        CurMetaTags=NULL;
+    AddEspProperty();
+ }
+ | EspTemplateStart ESPTEMPLATE '<' EspTemplateParams '>' ID EspPropertyInit ';'
  {
     if (CurParam)
     {

+ 1 - 0
tools/esdlcomp/esdllex.l

@@ -54,6 +54,7 @@ ESPservice  { if (check_return( ESPSERVICE )) return ESPSERVICE; }
 ESPmethod   { if (check_return( ESPMETHOD )) return ESPMETHOD; }
 ESPmount    { if (check_return( ESPMOUNT )) return ESPMOUNT; }
 ESParray    { yylval.setName((const char *) yytext); if (check_return( ESPTEMPLATE )) return ESPTEMPLATE; }
+ESPlist     { yylval.setName((const char *) yytext); if (check_return( ESPTEMPLATELIST )) return ESPTEMPLATELIST; }
 ESPuses     { if (check_return( ESPUSES )) return ESPUSES; }
 ESPinclude  { if (check_return( ESPINCLUDE )) return ESPINCLUDE; }
 ESPVersionDef   { if (check_return( ESPVERSIONDEF )) return ESPVERSIONDEF; }