@@ -46,6 +46,9 @@ abstract class Saver {
46
46
47
47
private SaveCur _cur ;
48
48
49
+ protected boolean _isTopLevelElement = true ;
50
+ protected final Map <String , String > _extraNamespaces ;
51
+
49
52
private List <String > _ancestorNamespaces ;
50
53
private final Map <String , String > _suggestedPrefixes ;
51
54
protected XmlOptionCharEscapeMap _replaceChar ;
@@ -135,6 +138,8 @@ protected void syntheticNamespace(String prefix, String uri, boolean considerDef
135
138
_suggestedPrefixes = options .getSaveSuggestedPrefixes ();
136
139
137
140
_ancestorNamespaces = _cur .getAncestorNamespaces ();
141
+
142
+ _extraNamespaces = options .getSaveExtraNamespaces ();
138
143
}
139
144
140
145
private static SaveCur createSaveCur (Cur c , XmlOptions options ) {
@@ -287,10 +292,12 @@ protected final boolean process() {
287
292
switch (_cur .kind ()) {
288
293
case ROOT : {
289
294
processRoot ();
295
+ _isTopLevelElement = true ;
290
296
break ;
291
297
}
292
298
case ELEM : {
293
299
processElement ();
300
+ _isTopLevelElement = false ;
294
301
break ;
295
302
}
296
303
case -ELEM : {
@@ -899,6 +906,8 @@ protected boolean emitElement(SaveCur c, List<QName> attrNames, List<String> att
899
906
emitNamespacesHelper ();
900
907
}
901
908
909
+ emitExtraNamespacesHelper ();
910
+
902
911
for (int i = 0 ; i < attrNames .size (); i ++) {
903
912
emitAttrHelper (attrNames .get (i ), attrValues .get (i ));
904
913
}
@@ -943,6 +952,17 @@ protected void emitXmlns(String prefix, String uri) {
943
952
emit ('"' );
944
953
}
945
954
955
+ private void emitExtraNamespacesHelper () {
956
+ if (!_isTopLevelElement || null == _extraNamespaces )
957
+ return ;
958
+
959
+ for (Map .Entry <String , String > nsEntry : _extraNamespaces .entrySet ()) {
960
+ emit (' ' );
961
+ emitXmlns (nsEntry .getKey (), nsEntry .getValue ());
962
+ }
963
+
964
+ }
965
+
946
966
private void emitNamespacesHelper () {
947
967
LinkedHashMap <String , String > nsMap = new LinkedHashMap <>();
948
968
for (iterateMappings (); hasMapping (); nextMapping ()) {
@@ -1853,6 +1873,8 @@ protected boolean emitElement(SaveCur c, List<QName> attrNames, List<String> att
1853
1873
emit ('<' );
1854
1874
emitName (c .getName (), false );
1855
1875
1876
+ emitExtraNamespacesHelper ();
1877
+
1856
1878
for (int i = 0 ; i < attrNames .size (); i ++) {
1857
1879
emitAttrHelper (attrNames .get (i ), attrValues .get (i ));
1858
1880
}
@@ -1902,6 +1924,15 @@ private void emitNamespacesHelper() {
1902
1924
}
1903
1925
}
1904
1926
1927
+ private void emitExtraNamespacesHelper () {
1928
+ if (!_isTopLevelElement || null == _extraNamespaces )
1929
+ return ;
1930
+ for (Map .Entry <String , String > nsEntry : _extraNamespaces .entrySet ()) {
1931
+ emit (' ' );
1932
+ emitXmlns (nsEntry .getKey (), nsEntry .getValue ());
1933
+ }
1934
+ }
1935
+
1905
1936
private void emitAttrHelper (QName attrName , String attrValue ) {
1906
1937
emit (' ' );
1907
1938
emitName (attrName , true );
@@ -2578,6 +2609,15 @@ private String getPrefixedName(QName name) {
2578
2609
return prefix + ":" + local ;
2579
2610
}
2580
2611
2612
+ private void emitExtraNamespacesHelper () {
2613
+ if (!_isTopLevelElement || null == _extraNamespaces || !_nsAsAttrs )
2614
+ return ;
2615
+ for (Map .Entry <String , String > nsEntry : _extraNamespaces .entrySet ()) {
2616
+ String prefix = nsEntry .getKey ();
2617
+ _attributes .addAttribute ("http://www.w3.org/2000/xmlns/" , prefix , "xmlns:" + prefix , "CDATA" , nsEntry .getValue ());
2618
+ }
2619
+ }
2620
+
2581
2621
private void emitNamespacesHelper () {
2582
2622
for (iterateMappings (); hasMapping (); nextMapping ()) {
2583
2623
String prefix = mappingPrefix ();
@@ -2607,6 +2647,8 @@ protected boolean emitElement(SaveCur c, List<QName> attrNames, List<String> att
2607
2647
emitNamespacesHelper ();
2608
2648
}
2609
2649
2650
+ emitExtraNamespacesHelper ();
2651
+
2610
2652
for (int i = 0 ; i < attrNames .size (); i ++) {
2611
2653
QName name = attrNames .get (i );
2612
2654
0 commit comments