@@ -42,6 +42,13 @@ public class Xpp3DomUtils
42
42
public static final String SELF_COMBINATION_OVERRIDE = "override" ;
43
43
44
44
public static final String SELF_COMBINATION_MERGE = "merge" ;
45
+
46
+ /**
47
+ * In case of complex XML structures, combining can be done based on id.
48
+ *
49
+ * @since 3.0.22
50
+ */
51
+ public static final String ID_COMBINATION_MODE_ATTRIBUTE = "combine.id" ;
45
52
46
53
/**
47
54
* This default mode for combining a DOM node during merge means that where element names
@@ -71,7 +78,7 @@ public void writeToSerializer( String namespace, XmlSerializer serializer, Xpp3D
71
78
* 1. if the recessive DOM is null, there is nothing to do...return.
72
79
*
73
80
* 2. Determine whether the dominant node will suppress the recessive one (flag=mergeSelf).
74
- *
81
+ *
75
82
* A. retrieve the 'combine.self' attribute on the dominant node, and try to match against 'override'...
76
83
* if it matches 'override', then set mergeSelf == false...the dominant node suppresses the recessive
77
84
* one completely.
@@ -99,10 +106,13 @@ public void writeToSerializer( String namespace, XmlSerializer serializer, Xpp3D
99
106
*
100
107
* D. Iterate through the recessive children, and:
101
108
*
102
- * i. if mergeChildren == true and there is a corresponding dominant child (matched by element name),
109
+ * i. if 'combine.id' is set and there is a corresponding dominant child (matched by value of 'combine.id'),
110
+ * merge the two.
111
+ *
112
+ * ii. if mergeChildren == true and there is a corresponding dominant child (matched by element name),
103
113
* merge the two.
104
114
*
105
- * ii. otherwise, add the recessive child as a new child on the dominant root node.
115
+ * iii. otherwise, add the recessive child as a new child on the dominant root node.
106
116
*/
107
117
private static void mergeIntoXpp3Dom ( Xpp3Dom dominant , Xpp3Dom recessive , Boolean childMergeOverride )
108
118
{
@@ -115,7 +125,7 @@ private static void mergeIntoXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive, Boole
115
125
boolean mergeSelf = true ;
116
126
117
127
String selfMergeMode = dominant .getAttribute ( SELF_COMBINATION_MODE_ATTRIBUTE );
118
-
128
+
119
129
if ( isNotEmpty ( selfMergeMode ) && SELF_COMBINATION_OVERRIDE .equals ( selfMergeMode ) )
120
130
{
121
131
mergeSelf = false ;
@@ -154,16 +164,35 @@ private static void mergeIntoXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive, Boole
154
164
}
155
165
156
166
Xpp3Dom [] children = recessive .getChildren ();
157
- for ( Xpp3Dom child : children )
167
+ for ( Xpp3Dom recessiveChild : children )
158
168
{
159
- Xpp3Dom childDom = dominant .getChild ( child .getName () );
169
+ String idValue = recessiveChild .getAttribute ( ID_COMBINATION_MODE_ATTRIBUTE );
170
+
171
+ Xpp3Dom childDom = null ;
172
+ if ( isNotEmpty ( idValue ) )
173
+ {
174
+ for ( Xpp3Dom dominantChild : dominant .getChildren () )
175
+ {
176
+ if ( idValue .equals ( dominantChild .getAttribute ( ID_COMBINATION_MODE_ATTRIBUTE ) ) )
177
+ {
178
+ childDom = dominantChild ;
179
+ // we have a match, so don't append but merge
180
+ mergeChildren = true ;
181
+ }
182
+ }
183
+ }
184
+ else
185
+ {
186
+ childDom = dominant .getChild ( recessiveChild .getName () );
187
+ }
188
+
160
189
if ( mergeChildren && childDom != null )
161
190
{
162
- mergeIntoXpp3Dom ( childDom , child , childMergeOverride );
191
+ mergeIntoXpp3Dom ( childDom , recessiveChild , childMergeOverride );
163
192
}
164
193
else
165
194
{
166
- dominant .addChild ( new Xpp3Dom ( child ) );
195
+ dominant .addChild ( new Xpp3Dom ( recessiveChild ) );
167
196
}
168
197
}
169
198
}
0 commit comments