1. 程式人生 > >解決JSON Lib, XML轉JSON字串不要namespace,以及當xml中有Type屬性時轉換成json會丟失問題

解決JSON Lib, XML轉JSON字串不要namespace,以及當xml中有Type屬性時轉換成json會丟失問題

XMLSerializer xmlSerializer = new XMLSerializer();  
JSON json = xmlSerializer.read(xml);  
return json.toString(3);

以上程式碼在xmll轉成json字串後,json字串裡會含有namespace屬性,把下面的xml片斷

<openremote xmlns="http://www.openremote.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:schemaLocation="http://www.openremote.org/panel.xsd">  

轉為

{  
"@xmlns": "http://www.openremote.org",  
"@xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",  
"@xmlns:schemaLocation": "http://www.openremote.org/panel.xsd"  
}  

但是這恰好是我不想要的屬性。不用擔心,只需給XMLSerializer加上設定屬性skipNamespace為true即可,如下

XMLSerializer xmlSerializer = new XMLSerializer();  
xmlSerializer.setSkipNamespaces(true);  
JSON json = xmlSerializer.read(xml);  
return json.toString(3);  

 好,這一點就告一段落.

 現在我又遇到了一個問題,那就是在xml裡屬性名為type的屬性在轉換後的json字串中丟失了, 同樣這一點也不用太擔心,我看了一下XMLSerialzer的原始碼,發現XMLSerializer的構造器是這樣寫的:

public XMLSerializer() {  
      setObjectName( "o" );  
      setArrayName( "a" );  
      setElementName( "e" );  
      setTypeHintsEnabled( true );  
      setTypeHintsCompatibility( true );  
      setNamespaceLenient( false );  
      setSkipNamespaces( false );  
      setRemoveNamespacePrefixFromElements( false );  
      setTrimSpaces( false );  
      setExpandableProperties( EMPTY_ARRAY );  
      setSkipNamespaces( false );  
   }  

其中

setTypeHintsEnabled( true );  
setTypeHintsCompatibility( true ); 

就在搞鬼了, 因為在XMLSerialzer的

private JSON processObjectElement( Element element, String defaultType )  

方法中還有這麼一段把xml轉為json的程式碼,如下:

// process attributes first  
int attrCount = element.getAttributeCount();  
for( int i = 0; i < attrCount; i++ ){  
   Attribute attr = element.getAttribute( i );  
   String attrname = attr.getQualifiedName();  
   if( isTypeHintsEnabled()  
         && (addJsonPrefix( "class" ).compareToIgnoreCase( attrname ) == 0 || addJsonPrefix(  
               "type" ).compareToIgnoreCase( attrname ) == 0) ){  
      continue;  
   }  
   String attrvalue = attr.getValue();  
   setOrAccumulate( jsonObject, "@" + removeNamespacePrefix( attrname ),  
         trimSpaceFromValue( attrvalue ) );  
}  

addJsonPrefix的程式碼片斷為

private String addJsonPrefix( String str ) {  
   if( !isTypeHintsCompatibility() ){  
      return JSON_PREFIX + str;  
   }  
   return str;  
}  

現在,你應該很清楚的可以看到當在構造器中

setTypeHintsEnabled(true);  
setTypeHintsCompatibility(true);   

 的時候

if( isTypeHintsEnabled()  
               && (addJsonPrefix( "class" ).compareToIgnoreCase( attrname ) == 0 || addJsonPrefix(  
                     "type" ).compareToIgnoreCase( attrname ) == 0) )  

也為true.

 這樣的話,type這個屬性就被pass掉了。

所以,為了讓type這個比較特殊的屬效能在轉換後的json字答串中出現,你只需對XMLSerialzer的例項這樣做:

setTypeHintsEnabled(false); 

 或

setTypeHintsCompatibility(false);  

 或

setTypeHintsEnabled(false);  
setTypeHintsCompatibility(false);

也就是說,反正讓

if( isTypeHintsEnabled()  
               && (addJsonPrefix( "class" ).compareToIgnoreCase( attrname ) == 0 || addJsonPrefix(  
                     "type" ).compareToIgnoreCase( attrname ) == 0) )  

為false就行,這樣在xml中有type這個屬性的時候就會轉換為 "@type":"xxxx"

OK, 我的問題也解決。希望可以給你帶來幫助。