2121
2222import org .apache .axiom .om .OMElement ;
2323import org .apache .axiom .om .OMXMLBuilderFactory ;
24- import org .apache .axiom .om .OMXMLParserWrapper ;
2524import org .apache .xmlbeans .XmlObject ;
2625import org .mozilla .javascript .Context ;
2726import org .mozilla .javascript .Scriptable ;
3332 * JSObjectConvertor converts between OMElements and JavaScript E4X XML objects
3433 */
3534public class JSOMElementConvertor extends DefaultOMElementConvertor {
36-
37- protected Scriptable scope ;
38-
39- public JSOMElementConvertor () {
40- Context cx = Context .enter ();
41- try {
42- this .scope = cx .initStandardObjects ();
43- } finally {
44- Context .exit ();
45- }
46- }
47-
4835 public Object toScript (OMElement o ) {
4936 XmlObject xml ;
5037 try {
@@ -55,30 +42,65 @@ public Object toScript(OMElement o) {
5542
5643 Context cx = Context .enter ();
5744 try {
45+ // Enable E4X support
46+ cx .setLanguageVersion (Context .VERSION_1_6 );
47+ Scriptable tempScope = cx .initStandardObjects ();
5848
59- Object wrappedXML = cx .getWrapFactory ().wrap (cx , scope , xml , XmlObject .class );
60- Scriptable jsXML = cx .newObject (scope , "XML" , new Object [] { wrappedXML });
61-
62- return jsXML ;
63-
49+ // Wrap the XmlObject directly
50+ return cx .getWrapFactory ().wrap (cx , tempScope , xml , XmlObject .class );
6451 } finally {
6552 Context .exit ();
6653 }
6754 }
6855
6956 public OMElement fromScript (Object o ) {
70- if (!(o instanceof XMLObject )) {
57+ if (!(o instanceof XMLObject ) && !( o instanceof Wrapper ) ) {
7158 return super .fromScript (o );
7259 }
7360
74- // TODO: E4X Bug? Shouldn't need this copy, but without it the outer element gets lost. See Mozilla bugzilla 361722
75- Scriptable jsXML = (Scriptable ) ScriptableObject .callMethod ((Scriptable ) o , "copy" , new Object [0 ]);
76- Wrapper wrapper = (Wrapper ) ScriptableObject .callMethod ((XMLObject )jsXML , "getXmlObject" , new Object [0 ]);
77- XmlObject xmlObject = (XmlObject )wrapper .unwrap ();
78- OMXMLParserWrapper builder = OMXMLBuilderFactory .createOMBuilder (xmlObject .newInputStream ());
79- OMElement omElement = builder .getDocumentElement ();
61+ try {
62+ XmlObject xmlObject = null ;
63+
64+ // Handle wrapped XmlObject
65+ if (o instanceof Wrapper ) {
66+ Object unwrapped = ((Wrapper ) o ).unwrap ();
67+ if (unwrapped instanceof XmlObject ) {
68+ xmlObject = (XmlObject ) unwrapped ;
69+ }
70+ }
8071
81- return omElement ;
82- }
72+ // If we have an XMLObject but not a wrapped XmlObject, try the old approach
73+ if (xmlObject == null && o instanceof XMLObject ) {
74+ // TODO: E4X Bug? Shouldn't need this copy, but without it the outer element gets lost. See Mozilla bugzilla 361722
75+ XMLObject jsXML = (XMLObject ) ScriptableObject .callMethod ((XMLObject ) o , "copy" , new Object [0 ]);
76+
77+ // get proper XML representation from toXMLString()
78+ String xmlString ;
79+ try {
80+ // Try toXMLString() method first
81+ xmlString = (String ) ScriptableObject .callMethod (jsXML , "toXMLString" , new Object [0 ]);
82+ } catch (Exception toXMLException ) {
83+ // If toXMLString() doesn't work, try toString()
84+ xmlString = jsXML .toString ();
85+ }
8386
87+ // Remove extra whitespace to match expected format
88+ String normalizedXML = xmlString .replaceAll (">\\ s+<" , "><" ).trim ();
89+ return OMXMLBuilderFactory
90+ .createOMBuilder (new java .io .StringReader (normalizedXML ))
91+ .getDocumentElement ();
92+ }
93+
94+ if (xmlObject != null ) {
95+ return OMXMLBuilderFactory
96+ .createOMBuilder (xmlObject .newInputStream ())
97+ .getDocumentElement ();
98+ } else {
99+ throw new RuntimeException ("Unable to extract XmlObject from JavaScript object" );
100+ }
101+
102+ } catch (Exception e ) {
103+ throw new RuntimeException ("Failed to convert JavaScript XML to OMElement: " + e .getMessage (), e );
104+ }
105+ }
84106}
0 commit comments