Here is my xml that I want to translate.
<?xml version="1.0" encoding="UTF-8" ?>
<Loop xmlns="http://www.example.org">
<Loop-2000A>
<Element-628>81</Element-628>
<Element-734 nil="nil82"/>
<Element-735>83</Element-735>
<Element-736>84</Element-736>
</Loop-2000A>
<Loop-2000B>
<Element-1035>85</Element-1035>
<Element-1036 nil="nil86"/>
<Element-1037>87</Element-1037>
</Loop-2000B>
<Loop-2000B>
<Element-1035>98</Element-1035>
<Element-1036 nil="nil86"/>
<Element-1037>97</Element-1037>
</Loop-2000B>
<Loop-2000C>
<Element-1031>86</Element-1031>
<Element-1039 nil="nil86"/>
<Element-1038>25</Element-1038>
</Loop-2000C>
<Loop-2000A>
<Element-628>89</Element-628>
<Element-734 nil="nil82"/>
<Element-735>99</Element-735>
<Element-736>109</Element-736>
</Loop-2000A>
<Loop-2000B>
<Element-1035>208</Element-1035>
<Element-1036 nil="nil86"/>
<Element-1037>87</Element-1037>
</Loop-2000B>
<Loop-2000C>
<Element-1031>92</Element-1031>
<Element-1039 nil="nil86"/>
<Element-1038>90</Element-1038>
</Loop-2000C>
<Loop-2000B>
<Element-1035>209</Element-1035>
<Element-1036 nil="nil86"/>
<Element-1037>97</Element-1037>
</Loop-2000B>
</Loop>
The requirement is to make the ...Loop-2000A parents of ...Loop-2000B ..and Loop-2000B Parents of 2000-C . Loop2000-C is optional in source xml.Other Loop in xml which are outside Loop-2000A should be transformed as it is. Hence, the transformed XML should look something like this.
<?xml version = '1.0' encoding = 'UTF-8'?>
<ns2:TargetLoop xmlns:ns2="http://www.target.org">
<Loop-2000A>
<Loop-2000B>
<Element-1035>85</Element-1035>
<Element-1036 nil="nil86"/>
<Element-1037>87</Element-1037>
</Loop-2000B>
<Loop-2000B>
<Element-1035>98</Element-1035>
<Element-1036 nil="nil86"/>
<Element-1037>97</Element-1037>
<Loop-2000C>
<Element-1031>86</Element-1031>
<Element-1039 nil="nil86"/>
<Element-1038>25</Element-1038>
</Loop-2000C>
</Loop-2000B>
<Element-628>81</Element-628>
<Element-734 nil="nil82"/>
<Element-735>83</Element-735>
<Element-736>84</Element-736>
</Loop-2000A>
<Loop-2000A>
<Loop-2000B>
<Element-1035>208</Element-1035>
<Element-1036 nil="nil86"/>
<Element-1037>87</Element-1037>
<Loop-2000C>
<Element-1031>92</Element-1031>
<Element-1039 nil="nil86"/>
<Element-1038>90</Element-1038>
</Loop-2000C>
</Loop-2000B>
<Loop-2000B>
<Element-1035>209</Element-1035>
<Element-1036 nil="nil86"/>
<Element-1037>97</Element-1037>
</Loop-2000B>
<Element-628>89</Element-628>
<Element-734 nil="nil82"/>
<Element-735>99</Element-735>
<Element-736>109</Element-736>
</Loop-2000A>
</Loop>
Any suggestions would be appreciated
In XSLT 2.0, you could have probably made use of xsl:for-each-group, using its group-starting-with attribute. In XSLT 1.0 though, this can be achieved by use of keys. You can define a key to look up the Loop-2000B elements by their first preceding Loop-2000A element
Similarlym you could do the same for associating Loop-2000C elements by their first preceding Loop-2000B element (Although this may not be necessary if you say there can be at most only one Loop-2000C element for each Loop-2000B
The generate-id function is an XSLT function that can be used to generate a unique id for each node (If one of their existing child elements could uniquely identify the element, you could also use that). Note the use of the ex: prefix is because all the elements in your XML are in a namespace, so XSLT needs to know which namespaces elements are in.
In your XSLT you would start off by selecting just the Loop-2000A elements.
Then, within the template that matches ex:Loop-2000A you would select all the associated ex:Loop-2000B elements using the key
You would take a similar approach for getting the ex:Loop-2000C in the template that matches ex:Loop-2000B. Although, if there was ever only going to be at most one such ex:Loop-2000C element, you could do this and not worry about the key in this case:
This gets the very following sibling element, but only if it is a Loop-2000C element.
Finally, other existing elements can be matched and copied with the Identity Transform
Try this XSLT