Ext2.0 与服务端XML的交互(扩展Ext.data.XmlReader )

 本文案例如下:后台使用C#写的webservice,返回一个xml串作为结果集。前端需要对xml结果解析,放入到一个表格中。

以前没用Ext的解决办法是 :前台写xsl 转换xml ,把结果放入某个div内。。。优点是灵活多样,缺点是需要手写xsl代码,并对开发人员的dom以及css技术有比较高的要求。
现在有了漂亮贼酷的Ext ,没有理由不选它。 于是用Ext.data.XmlReader 读取服务器传回来的xml,本以为跟读取xml文件一样,读取url就ok了。但是代码一写。问题出现了。
我的代码如下:
 1 
 2  Ext.onReady(function(){ 
 3      var cm  =   new  Ext.grid.ColumnModel([
 4          {header: ' 编号 ' ,dataIndex: ' id ' },
 5          {header: ' 性别 ' ,dataIndex: ' sex ' },
 6          {header: ' 姓名 ' ,dataIndex: ' name ' },
 7          {header: ' 描述 ' ,dataIndex: ' descn ' }
 8      ]);
 9      cm.defaultSortable  =   true ;
10 
11      var CARTOON_WSDL_ADDR     =   " http://localhost/JMAMCCTV/JUUMSystemService/UUMSystemService.asmx " ;
12 
13      var dataStore  =   new  Ext.data.Store({
14                  url: CARTOON_WSDL_ADDR + ' /testXmlpage ' ,
15                  reader:  new  Ext.data.XmlReader({
16                      totalRecords:  " results " ,
17                      record:  " item "
18                  }, [                
19                  { name:  " id "  },{ name:  " sex "  },{ name:  " name "  },{ name:  " descn "  }
20                  ])
21              });    
22                  
23 
24 
25      var grid  =   new  Ext.grid.GridPanel({
26              renderTo:  ' testLayout ' ,
27              ds: dataStore,
28              cm: cm,
29              height: 200 ,
30              width: 500
31              title:  ' PagerCkp '
32          });
33          
34      dataStore.load({
35           params : {
36              pageindex: 1 ,pageCount: 2
37          },
38          callback: function(r, options, success) {
39                   // alert(dataStore.getTotalCount() );  // 取得记录总数。即 results 节点中的值
40                   // alert(dataStore.getCount() );  // 取得记录数。即 返回的xml中真实的记录数
41               if  (success  &&  r.length  >   0 ) {
42                  var ss  =  r[ 0 ]. get ( " id " );
43                   // alert(ss);
44              }
45               else {
46              }
47          }
48      })
49  });

alert出来的dataStore.getCount始终是0 。也就是 没有读出来webservice返回的xml串。

仔细查找问题所在。查看了Ext.data.XmlReader类 的源码,看到原来Ext.data.XmlReader 直接使用了 responseXML:
 
1    var doc  =  response.responseXML;
2           if ( ! doc) {
3               throw  {message:  " XmlReader.read: XML Document not available " };
4          }
5           return   this .readRecords(doc);

而大家知道webservice返回的responseXML 肯定是一个Xml对象。你的xml串就是被转义并放在 responseXML的根节点的text里的。比如本例:responseXML
对象的 xml 如下:
<? xml version = \ " 1.0\ " ?>
< string  xmlns = \ " http://www.mycompany.com/webservices/\ " >& lt;dataset & gt & lt;results & gt; 10 & lt; / results & gt; & lt;item & gt; & lt;id & gt; 1 & lt; / id & gt; & lt;sex & gt;男 & lt; / sex & gt; & lt;name & gt;JasonWoo & lt; / name & gt;  & lt;descn & gt;US.Ny & lt; / descn & gt; & lt; / item & gt; & lt;item & gt; & lt;id & gt; 2 & lt; / id & gt; & lt;sex & gt;女 & lt; / sex & gt; & lt;name & gt;Lucy & lt; / name & gt; & lt;descn & gt;CN.BJ & lt; / descn & gt;  & lt; / item & gt; & lt; / dataset & gt; </ string >
可以看到,你想要的string类型的xml串被放在<string>节点里并被转义了,Ext.data.XmlReader并没有读取到你的xml串。
找到问题后,就考虑解决办法,扩展一下Ext.data.XmlReader。 让它读取responseXML的根节点下的xml串:
  1  /**//* *
  2   * @author punkChen
  3    */
  4   
  5    // 先对xml对象进行封装。因为很遗憾没有找到ext对其的封装。哪位朋友找到后可以告知。
  6  function XmlDoc()
  7  {
  8      var tXmlDoc  =   false ;
  9       if (window.ActiveXObject)
 10      {
 11          var tMsXmlDomType  =  [ " Msxml2.DOMDocument.5.0 " " Msxml2.DOMDocument.4.0 " " Msxml2.DOMDocument.3.0 " " MSXML2.DOMDocument " " MSXML.DOMDocument " " Microsoft.XMLDOM " ];
 12           for (var i = 0 ;i < tMsXmlDomType.length;i ++ )
 13          {
 14               try
 15              {
 16                  tXmlDoc  =   new  ActiveXObject(tMsXmlDomType[i]);
 17                  tXmlDoc.setProperty( " SelectionLanguage " " XPath " );
 18                   break ;
 19              }
 20               catch (ex){}
 21          }    
 22      }
 23       else   if (document.implementation  &&  document.implementation.createDocument)
 24      {
 25          tXmlDoc  =  document.implementation.createDocument( "" , "" , null );     
 26           //  for safari,opera
 27           if ( ! tXmlDoc.load)
 28          { 
 29              tXmlDoc.async  =   true ;
 30              tXmlDoc.hp  =   new  XMLHttpRequest();
 31              tXmlDoc.onload  =  function(){};
 32              tXmlDoc.hp.hpOwner  =  tXmlDoc;
 33              tXmlDoc.hp.onreadystatechange  =  function()
 34              {
 35                   if  (tXmlDoc.hp.readyState  ==   4 )
 36                  {
 37                      var _result  =  tXmlDoc.hp.responseXML;          
 38                      tXmlDoc.onload(_result);   
 39                  }
 40              }
 41              tXmlDoc.hp.load  =  function(sUrl)
 42              {      
 43                   try
 44                  { 
 45                       this .open( " GET " , sUrl,  this .hpOwner.async);
 46                       this .send( null );     
 47                  }
 48                   catch (ex)
 49                  {
 50                       throw   " you can't connect the page using different domain,if you not config the Server-Side code " ;
 51                  }
 52                   if  ( ! this .hpOwner.async)
 53                  {
 54                      var _result  =   this .responseXML;
 55                       while  ( this .hpOwner.hasChildNodes())
 56                           this .hpOwner.removeChild( this .hpOwner.lastChild);           
 57                       for  (var i  =   0 ; i  <  _result.childNodes.length; i ++
 58                      {
 59                           this .hpOwner.appendChild( this .hpOwner.importNode(_result.childNodes[i],  true ));
 60                      }
 61                  }
 62              }    
 63              tXmlDoc.load  =  function(sUrl)
 64              {
 65                    tXmlDoc.hp.load(sUrl);
 66              }      
 67          }        
 68           //  apply to ie
 69          tXmlDoc.onreadystatechange  =  function(){};    
 70          tXmlDoc.readyState  =   4 ;   //  because other browers not this property
 71          tXmlDoc.onload  =  function(s)
 72          {    
 73               if (tXmlDoc.hp)
 74              {
 75                  var _result  =  s;
 76                   while  ( this .hasChildNodes())
 77                       this .removeChild( this .lastChild);           
 78                   for  (var i  =   0 ; i  <  _result.childNodes.length; i ++
 79                  {
 80                       this .appendChild( this .importNode(_result.childNodes[i],  true ));
 81                  }       
 82              }
 83               this .readyState  =   4 ;
 84               this .onreadystatechange(s);
 85          }      
 86           // apply load xml string funciton
 87          tXmlDoc.loadXML  =  function (s) 
 88          {   
 89              var doc2  =  ( new  DOMParser()).parseFromString(s,  " text/xml " );  
 90              var roottag  =  doc2.documentElement;
 91               if  ((roottag.tagName  ==   " parserError " ||  (roottag.namespaceURI  ==   " http://www.mozilla.org/newlayout/xml/parsererror.xml " ))
 92              {
 93                  var _sourceText  =  roottag.lastChild.firstChild.nodeValue;
 94                   throw  ( " load XML by string happen error,error detail:\n "   +  roottag.firstChild.nodeValue + " \n " + _sourceText);
 95                   return   false ;
 96              }    
 97               while  ( this .hasChildNodes())
 98                   this .removeChild( this .lastChild);           
 99               for  (var i  =   0 ; i  <  doc2.childNodes.length; i ++
100              {
101                   this .appendChild( this .importNode(doc2.childNodes[i],  true ));
102              }
103               this .onreadystatechange();     
104          }
105      }
106       if ( ! tXmlDoc)
107      {
108           throw  ( " Can not create xml doc object! " );
109      }
110       return  tXmlDoc;
111  }
112 
113 
114  // 扩展Ext.data.XmlReader
115  Ext.data.XmlReaderExForService  =  Ext.extend(Ext.data.XmlReader, {
116 
117      read : function(response){
118          var tmpdoc  =  response.responseXML;
119           if ( ! tmpdoc) {
120               throw  {message:  " XmlReader.read: XML Document not available " };
121          }
122                  
123          var doc  =   new  XmlDoc();
124          
125           if (window.ActiveXObject){
126              doc.loadXML(tmpdoc.text);
127          }
128           else {
129              doc.loadXML(tmpdoc.firstChild.textContent);
130          }
131           if ( ! doc) {
132               throw  {message:  " XmlReader.read: XML Document not available " };
133          }
134           return   this .readRecords(doc);
135      },
136 
137      
138      readRecords : function(doc){
139          
140           this .xmlData  =  doc;
141          var root  =  doc.documentElement  ||  doc;
142          var q  =  Ext.DomQuery;
143          var recordType  =   this .recordType, fields  =  recordType.prototype.fields;
144          var sid  =   this .meta.id;
145          var totalRecords  =   0 , success  =   true ;
146           if ( this .meta.totalRecords){
147              totalRecords  =  q.selectNumber( this .meta.totalRecords, root,  0 );
148          }
149 
150           if ( this .meta.success){
151              var sv  =  q.selectValue( this .meta.success, root,  true );
152              success  =  sv  !==   false   &&  sv  !==   ' false ' ;
153          }
154          var records  =  [];
155          var ns  =  q.select( this .meta.record, root);
156           for (var i  =   0 , len  =  ns.length; i  <  len; i ++ ) {
157              var n  =  ns[i];
158              var values  =  {};
159              var id  =  sid  ?  q.selectValue(sid, n) : undefined;
160               for (var j  =   0 , jlen  =  fields.length; j  <  jlen; j ++ ){
161                  var f  =  fields.items[j];
162                  var v  =  q.selectValue(f.mapping  ||  f.name, n, f.defaultValue);
163                  v  =  f.convert(v, n);
164                  values[f.name]  =  v;
165              }
166              var record  =   new  recordType(values, id);
167              record.node  =  n;
168              records[records.length]  =  record;
169          }
170 
171           return  {
172              success : success,
173              records : records,
174              totalRecords : totalRecords  ||  records.length
175          };
176      }
177  });
178 
179  Ext.reg( ' xmlreaderexfor ' , Ext.data.XmlReaderExForService);

把这个js文件引入到页面上,最后把原来第一段代码中的reader定义改为新的xmlreader即可:
reader:  new  Ext.data.XmlReaderExForService

在IE 7.0 和 firefox2.0 下测试通过。

你可能感兴趣的:(reader)