66public class RepeaterData
77{
88 private string Path { get ; set ; }
9- private XmlNode ? Node { get ; set ; }
10- private int iterationCount = 0 ;
9+ private List < XmlNode > ? Nodes { get ; set ; }
10+ private int iterationCount = 1 ;
1111
12- public RepeaterData ( string name , XmlNode ? node )
12+ private int iterationMax = 0 ;
13+
14+ public RepeaterData ( string name , XmlNode node , int fileLocalMax )
1315 {
1416 Path = name ;
15- if ( node != null )
17+ iterationMax = fileLocalMax ;
18+
19+ Nodes = new List < XmlNode > ( ) ;
20+ if ( node . HasChildNodes )
1621 {
17- Node = node ;
22+ foreach ( XmlNode childNode in node . ChildNodes )
23+ {
24+ Nodes . Add ( childNode ) ;
25+ }
1826 }
1927 else
2028 {
21- Node = null ;
2229 }
2330 }
2431
25- public RepeaterData ( string path )
32+
33+
34+
35+ public RepeaterData ( string path , int fileCount )
2636 {
2737 Path = path ;
28- Node = null ;
29-
38+ Nodes = null ;
39+ iterationMax = fileCount ;
3040 }
3141
3242 public string GetPath ( )
3343 {
3444 return Path ;
3545 }
36- public XmlNode ? GetNode ( )
46+ public List < XmlNode > GetNodes ( )
3747 {
38- return Node ;
48+ return Nodes ;
3949 }
40- public int getIterationCount ( )
50+ public int GetIterationCount ( )
4151 {
4252 return iterationCount ;
4353 }
4454 public int Iterate ( )
4555 {
56+ if ( iterationCount >= iterationMax )
57+ {
58+ return - 1 ;
59+ }
4660 iterationCount ++ ;
47- return iterationCount - 1 ;
61+ return iterationCount ;
4862 }
4963 }
5064
@@ -76,19 +90,100 @@ public void CreateReport(List<XMLFile> processedXmlFiles, XMLFile schemaFile)
7690 HandleTag ( node , processedXmlFiles ) ;
7791 }
7892
79- output . DumpToFile ( "outputBasic.csv" ) ;
93+ output . DumpToFile ( "outputIntermediate.csv" ) ;
94+ }
95+
96+ private int GetFirstNonNodeRepeaterIteration ( )
97+ {
98+ foreach ( var repeater in repeaterStack )
99+ {
100+ if ( repeater . GetNodes ( ) == null )
101+ {
102+ return repeater . GetIterationCount ( ) ;
103+ }
104+ }
105+ return - 1 ; // Meaningful value indicating no non-node repeater found
80106 }
81107
82108 private string getFieldValue ( string location , List < XMLFile > processedXmlFiles )
83109 {
84- foreach ( var xmlFile in processedXmlFiles )
110+ if ( repeaterStack . Count > 0 )
111+ {
112+ int fileIterationIndex = - 1 ;
113+ if ( repeaterStack . Peek ( ) . GetNodes ( ) != null )
114+ { //Checking if current repeater is on files or nodes
115+
116+ fileIterationIndex = GetFirstNonNodeRepeaterIteration ( ) ;
117+ if ( repeaterStack . Peek ( ) . GetIterationCount ( ) != - 1 )
118+ {
119+ // Build a new location string by splicing in repeater iteration indices
120+ string updatedLocation = location ;
121+ foreach ( var repeater in repeaterStack )
122+ {
123+ string path = repeater . GetPath ( ) ;
124+ int idx = updatedLocation . IndexOf ( path , StringComparison . Ordinal ) ;
125+ if ( idx != - 1 )
126+ {
127+ // Find the end of the path in the location string
128+ int pathEnd = idx + path . Length ;
129+ // Insert [iteration] after the path
130+ updatedLocation = updatedLocation . Substring ( 0 , pathEnd ) +
131+ $ "[{ repeater . GetIterationCount ( ) } ]" +
132+ updatedLocation . Substring ( pathEnd ) ;
133+ }
134+ }
135+ XmlNodeList ? nodes = null ;
136+
137+
138+ if ( fileIterationIndex != - 1 )
139+ {
140+ nodes = processedXmlFiles [ fileIterationIndex ] . GetDocument ( ) . SelectNodes ( updatedLocation ) ;
141+ }
142+ else
143+ {
144+ nodes = processedXmlFiles [ 0 ] . GetDocument ( ) . SelectNodes ( updatedLocation ) ;
145+ }
146+
147+ if ( nodes != null && nodes . Count > 0 )
148+ {
149+
150+ string returnValue = "" ;
151+ if ( updatedLocation == location )
152+ {
153+ returnValue = nodes [ 0 ] . InnerText ;
154+ } else {
155+
156+ returnValue = nodes [ 0 ] . InnerText ; //We spliced the location, therefore nodes[0] is the correct value
157+ }
158+ return returnValue ; // Return the first matching node's text
159+ }
160+ else
161+ {
162+ return "" ;
163+ }
164+ }
165+ }
166+ else //Repeater it is on Files.
167+ {
168+ var nodes = processedXmlFiles [ repeaterStack . Peek ( ) . GetIterationCount ( ) ] . GetDocument ( ) . SelectNodes ( location ) ;
169+ if ( nodes != null && nodes . Count > 0 )
170+ {
171+ return nodes [ 0 ] . InnerText ; // Return the first matching node's text
172+ }
173+ }
174+ }
175+ else
85176 {
86- var nodes = xmlFile . GetDocument ( ) . SelectNodes ( location ) ;
87- if ( nodes != null && nodes . Count > 0 )
177+ foreach ( var xmlFile in processedXmlFiles )
88178 {
89- return nodes [ 0 ] . InnerText ; // Return the first matching node's text
179+ var nodes = xmlFile . GetDocument ( ) . SelectNodes ( location ) ;
180+ if ( nodes != null && nodes . Count > 0 )
181+ {
182+ return nodes [ 0 ] . InnerText ; // Return the first matching node's text
183+ }
90184 }
91185 }
186+
92187 return "" ; // Return empty if no match found
93188 }
94189
@@ -109,16 +204,53 @@ private void HandleTag(XmlNode node, List<XMLFile> processedXmlFiles)
109204
110205 if ( node . HasChildNodes )
111206 {
112- foreach ( XmlNode childNode in node . ChildNodes )
207+ if ( node . Name == "Repeater" && repeaterStack . Count > 0 )
208+ {
209+ var currentRepeater = repeaterStack . Peek ( ) ;
210+ do
211+ {
212+ foreach ( XmlNode childNode in node . ChildNodes )
213+ {
214+ Serilog . Log . Information ( $ "Processing child of repeater node: { childNode . Name } ") ;
215+ HandleTag ( childNode , processedXmlFiles ) ;
216+ }
217+ output . OnEnterNewLine ( ) ;
218+ output . OnExitNewLine ( ) ;
219+ } while ( currentRepeater . Iterate ( ) != - 1 ) ;
220+ }
221+ else
113222 {
114- Serilog . Log . Information ( $ "Processing child node: { childNode . Name } " ) ;
115- // Here you would implement the logic to handle child nodes
116- // For example, you might want to recursively call a method to handle nested tags
117- HandleTag ( childNode , processedXmlFiles ) ;
223+ foreach ( XmlNode childNode in node . ChildNodes ) {
224+ Serilog . Log . Information ( $ "Processing child node: { childNode . Name } " ) ;
225+ HandleTag ( childNode , processedXmlFiles ) ;
226+ }
118227 }
228+
119229 }
120230 OnExitTag ( node , processedXmlFiles ) ;
121231 }
232+
233+ private int GetFileLocalMax ( string location , List < XMLFile > processedXmlFiles )
234+ {
235+ int fileVal = 0 ;
236+ if ( repeaterStack . Count > 0 )
237+ {
238+ foreach ( RepeaterData repeater in repeaterStack )
239+ {
240+ if ( repeater . GetNodes ( ) == null ) //This is our file Value
241+ {
242+ fileVal = repeater . GetIterationCount ( ) ;
243+ }
244+ }
245+ }
246+
247+ var nodes = processedXmlFiles [ fileVal ] . GetDocument ( ) . SelectNodes ( location ) ;
248+ if ( nodes != null )
249+ {
250+ return nodes . Count ;
251+ }
252+ return 0 ;
253+ }
122254
123255 private void OnEnterTag ( XmlNode node , List < XMLFile > processedXmlFiles )
124256 {
@@ -128,6 +260,16 @@ private void OnEnterTag(XmlNode node, List<XMLFile> processedXmlFiles)
128260 if ( node . Name == "Repeater" )
129261 {
130262 Serilog . Log . Information ( "Processing 'Repeater' tag logic here." ) ;
263+ if ( node . Attributes != null && node . Attributes [ "location" ] != null && node . Attributes [ "location" ] ? . Value != null )
264+ {
265+ repeaterStack . Push ( new RepeaterData ( node . Attributes [ "location" ] . Value , node , GetFileLocalMax ( node . Attributes [ "location" ] . Value , processedXmlFiles ) ) ) ;
266+ }
267+ else if ( node . Attributes != null && node . Attributes [ "special" ] != null && node . Attributes [ "special" ] ? . Value != null )
268+ {
269+ repeaterStack . Push ( new RepeaterData ( node . Attributes [ "special" ] . Value , processedXmlFiles . Count ) ) ;
270+ }
271+
272+
131273 }
132274 else if ( node . Name == "Field" )
133275 {
0 commit comments