/// <summary> /// Пишет XSLT для SQLStruct /// </summary> /// <param name="sql">Схема SQL</param> /// <param name="prevGroupCount">Номер предыдущей группировки</param> public void WriteXSL(SQLStruct sql, int prevGroupCount) { //tw.WriteLine("<xsl:variable name=\"" + sql.GetSQLUniqueName() + "\">"); if (sql.select.paint.Count > 0) { if (sql.select.KeyCount == 0) tw.WriteLine("<" + sql.As[0] + ">"); GroupBy(sql); WriteFrom(sql, DataSetName); if (sql.select.KeyCount != 0) { tw.Write("<" + sql.As[0] + ">"); for (int i=0;i<sql.select.KeyCount;i++) { string node = sql.select.GetKey(i); //tw.Write("<xsl:value-of select=\"$\"/>"); //string node = select[i]; string val = "$var_"+ sql.select.GetKeyTable(i) + "/" + node; //tw.WriteLine("<xsl:attribute name=\"" + node +"\" select=\"" + val + "\"/>"); tw.WriteLine("<xsl:attribute name=\"" + node +"\">"); tw.WriteLine("<xsl:value-of select=\"" + val + "\"/>"); tw.WriteLine("</xsl:attribute>"); } //tw.WriteLine(">"); } tw.WriteLine("<xsl:choose>"); for (int i=0;i<sql.select.paint.Count; i++) { string name = ""; if (sql.select.paint.By.table != null && sql.select.paint.By.table != "") name+="var_"+sql.select.paint.By.table + "/"; name += sql.select.paint.By.name; tw.WriteLine("<xsl:when test=\"$" + name + "='" + sql.select.paint.Val(i) + "'\">"); if (sql.select.selectType != SELECTTYPE.ONCE && sql.select.KeyCount == 0) { if (sql.select.UseTag == null) tw.WriteLine("<" +sql.select.paint[i] + ">"); else tw.WriteLine("<" + sql.select.UseTag + ">"); } WriteSelect(sql.select,sql); if (sql.select.selectType != SELECTTYPE.ONCE && sql.select.KeyCount == 0) { //tw.WriteLine("</tr-" + sql.from[0] + ">"); if (sql.select.UseTag == null) tw.WriteLine("</" + sql.select.paint[i] + ">"); else tw.WriteLine("</" + sql.select.UseTag + ">"); } tw.WriteLine("</xsl:when>"); } //Other tw.WriteLine("<xsl:otherwise>"); tw.WriteLine("<" + sql.select.paint.Other +">"); WriteSelect(sql.select,sql); tw.WriteLine("</" + sql.select.paint.Other +">"); tw.WriteLine("</xsl:otherwise>"); tw.WriteLine("</xsl:choose>"); if (sql.select.KeyCount != 0) tw.WriteLine("</" + sql.As[0] +">"); WriteFromEnd(sql); GroupByEnd1(sql, prevGroupCount); //Должны распечатать group if (sql.select.KeyCount == 0) tw.WriteLine("</" + sql.As[0] +">"); } else { if (sql.select.KeyCount == 0) tw.WriteLine("<" + sql.As[0] + ">"); GroupBy(sql); WriteFrom(sql, DataSetName); if (sql.select.KeyCount != 0) { tw.WriteLine("<" + sql.As[0] + ">"); for (int i=0;i<sql.select.KeyCount;i++) { string node = sql.select.GetKey(i); //tw.Write("<xsl:value-of select=\"$\"/>"); //string node = select[i]; string val = "$var_"+ sql.select.GetKeyTable(i) + "/" + node; //tw.WriteLine("<xsl:attribute name=\"" + node +"\" select=\"" + val + "\"/>"); tw.WriteLine("<xsl:attribute name=\"" + node +"\">"); tw.WriteLine("<xsl:value-of select=\"" + val + "\"/>"); tw.WriteLine("</xsl:attribute>"); } } if (sql.select.selectType != SELECTTYPE.ONCE && sql.select.KeyCount == 0) { if (sql.select.UseTag == null) { //tw.WriteLine("<tr-" + sql.from[0] + ">"); string trName = sql.GetTr(-1); tw.WriteLine("<" + trName + ">"); } else tw.WriteLine("<" + sql.select.UseTag + ">"); } WriteSelect(sql.select,sql); if (sql.select.selectType != SELECTTYPE.ONCE && sql.select.KeyCount == 0) { //tw.WriteLine("</tr-" + sql.from[0] + ">"); if (sql.select.UseTag == null) { string trName = sql.GetTr(-1); //tw.WriteLine("</tr-" + sql.from[0] + ">"); tw.WriteLine("</" + trName + ">"); } else tw.WriteLine("</" + sql.select.UseTag + ">"); } if (sql.select.KeyCount != 0) tw.WriteLine("</" + sql.As[0] +">"); WriteFromEnd(sql); GroupByEnd1(sql, prevGroupCount); if (sql.select.KeyCount == 0) tw.WriteLine("</" + sql.As[0] +">"); } //tw.WriteLine("</xsl:variable>"); //tw.WriteLine("<xsl:copy-of select=\"$" + sql.GetSQLUniqueName() + "\"/>"); }
/// <summary> /// Пишет закрывающие тэги группировок /// А так же добавляется тэги вставки данных из группировки /// </summary> /// <param name="sql">Схема SQL</param> /// <param name="prev"></param> public void GroupByEnd2(SQLStruct sql, int prev) { //Если нету group-a, то выходим //int id = 0; if (sql.group.Count <= 0) return; //Закрыввем данные tw.WriteLine("</xsl:variable>"); //Получаем имя тега TR (если оно есть) //string TrName = sql. string TrName = ""; for (int idGroup =0; idGroup < sql.group.Count; idGroup++) { //По idGroup получаем TrName = sql.GetTr(idGroup-1) + "/" +TrName; GroupOne(sql.group[idGroup], sql.idSQL, idGroup, prev, TrName); } tw.WriteLine("<xsl:copy-of select=\"$group_"+ sql.idSQL + "_"+ (sql.group.Count-1).ToString() + "\"/>"); }
/// <summary> /// Группировка данных( всех кроме ALL). Для каждой группировки текущего запроса создается тэг /// xsl:for-each-group и в нем пишется 2 переменные: /// group_key_id - значение ключя по которому идет группировка /// group_value_id - значение текущего узла (поддерево) /// Первый group извлекает данные из group_var_id (сюда были записаны данные из From) /// и последующие будут извлкать данные из current-group() /// /// /// </summary> /// <remarks>for-each-group созается для каждой переменной перечисленной в запросе</remarks> /// <param name="sql">SQL - запрос</param> /// <param name="prev"></param> /// <param name="max">Максимальое кол-во Group-ов (ВСЕ - ALL)</param> public void GroupNotAll(SQLStruct sql, int prev, int max) { string TrName = ""; int id= 0; for (int i=0;i<=max;i++) { TrName = sql.GetTr(i-1); if (TrName!=null) TrName = "/" + TrName; string VarGroupName = "group_" + i.ToString(); string from = "$group_var_" + id.ToString()+ TrName; if (i!=0) from = "current-group()" + TrName; //Далее в цикле мы группируем по каждой колонке для текущего group for (int j=0;j<sql.group[i].Count;j++) { if (j==0) tw.WriteLine("<xsl:for-each-group select=\"" + from + "\" group-by=\"" + sql.group[i].group[j] + "\">"); else tw.WriteLine("<xsl:for-each-group select=\"current-group()\" group-by=\"" + sql.group[i].group[j] + "\">"); tw.WriteLine("<xsl:variable name=\"" + VarGroupName+"_key_" + sql.group[i].group[j] + "\" select=\"current-grouping-key()\"/>"); tw.WriteLine("<xsl:variable name=\"" + VarGroupName+"_value_" + sql.group[i].group[j] + "\" select=\"current-group()\"/>"); } if (sql.group[i].type == TypeGroup.CONTAIN) GroupContain2(sql.group[i], sql.group[i].isAll, VarGroupName, TrName); else if (sql.group[i].type == TypeGroup.HEADER || sql.group[i].type == TypeGroup.HEADERFOOTER) GroupHeader2(sql.group[i], sql.group[i].isAll, VarGroupName, TrName); } }
/// <summary> /// Вызывается для группировки всех группировок кроме Group ALL /// При этом группировки пишутся с конца, начиная с MAX (необходимо потому чтобы отсеять уже сделанные GROUP ALL) /// В процедуре пробегаются все группировки текущего запроса, и для каждой вызываются необходимые функции, в конце дописываю закрывающийся for-each-group /// /// </summary> /// <param name="sql">Схема SQL</param> /// <param name="prev">не использутеся</param> /// <param name="max">Последний элемент</param> public void GroupNotAllEnd(SQLStruct sql, int prev, int max) { for (int i=max; i>=0; i--) { string TrName = ""; for (int j=0;j<=i;j++) { if (sql.GetTr(i-1) != null) { TrName = sql.GetTr(j-1) + "/" +TrName; } //TrName = sql.GetTr(j-1) + "/" +TrName; } string VarGroupName = "group_" + i.ToString(); if (sql.group[i].type == TypeGroup.CONTAIN) GroupContain2End(sql.group[i]); else if (sql.group[i].type == TypeGroup.FOOTER || sql.group[i].type == TypeGroup.HEADERFOOTER) GroupFooter2(sql.group[i], sql.group[i].isAll, VarGroupName, TrName); for (int j=0;j<sql.group[i].Count;j++) tw.WriteLine("</xsl:for-each-group>"); } }
/// <summary> /// Реализуется группировка Group ALL /// Реализовано путем определения типа текущей группировки (FLAT, CONTAIN...) и вызова соотв. функции для нее /// </summary> /// <remarks>Вызывает для написания промежуточного Group ALL (Не последнего). Но как выянилось потом, это не нужно. В точности повторяет <see cref="GroupAllEnd"/> за исключением того что, вызывается <see cref="GroupContain2"/> вместо <see cref="GroupContain2End"/> </remarks> /// <param name="sql">Схема Sql-запроса</param> /// <param name="groupall">Имя переменной из которой будут браться данные для группировки</param> /// <param name="Count">не нужен</param> public void GroupAll(SQLStruct sql, string groupall, int Count) { int idAll = -1; string TrName = ""; for (int i=0;i<sql.group.Count;i++) { //TrName = sql.GetTr(i-1) + "/" +TrName; if (sql.GetTr(i-1) != null) { TrName = sql.GetTr(i-1) + "/" +TrName; } if (sql.group[i].isAll) idAll = i; } if (idAll == -1) return; string VarGroupName = groupall; if (sql.group[idAll].type == TypeGroup.CONTAIN) GroupContain2(sql.group[idAll], true, groupall, TrName); else if (sql.group[idAll].type == TypeGroup.HEADER || sql.group[idAll].type == TypeGroup.HEADERFOOTER) GroupHeader2(sql.group[idAll], true, groupall, TrName); }
/// <summary> /// Реализуется группировка Group ALL /// Реализовано путем определения типа текущей группировки (FLAT, CONTAIN...) и вызова соотв. функции для нее /// </summary> /// <remarks>Вызывает для написания результирующего Group ALL</remarks> /// <param name="sql">Схема Sql-запроса</param> /// <param name="groupall">Имя переменной из которой будут браться данные для группировки</param> public void GroupAllEnd(SQLStruct sql, string groupall) { string VarGroupName = groupall; int idAll = -1; string TrName = ""; for (int i=0;i<sql.group.Count;i++) { TrName = sql.GetTr(i-1) + "/" +TrName; if (sql.group[i].isAll) idAll = i; } if (idAll == -1) return; if (sql.group[idAll].type == TypeGroup.CONTAIN) GroupContain2End(sql.group[idAll]); else if (sql.group[idAll].type == TypeGroup.FOOTER || sql.group[idAll].type == TypeGroup.HEADERFOOTER) GroupFooter2(sql.group[idAll], sql.group[idAll].isAll, groupall, TrName); }