本文案例如下:后台使用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 下测试通过。