js解析xml

js解析xml字符串

示例为DOMParser.parseFromString()的简单使用。
以下用到ES6的多行字符串,注意包含str值的两个点是Tab键上面、数字键1左边的按键,而不是单引号。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
function testXmlStr(){
var str = `<?xml version="1.0" encoding="utf-8"?><root>
<province name="北京直辖市">
<city>昌平区</city>
<city>朝阳区</city>
<city>崇文区</city>
<city>大兴区</city>
<city>东城区</city>
<city>房山区</city>
<city>丰台区</city>
<city>海淀区</city>
<city>怀柔区</city>
<city>门头沟区</city>
<city>密云区</city>
<city>平谷区</city>
<city>石景山区</city>
<city>顺义区</city>
<city>通州区</city>
<city>西城区</city>
<city>宣武区</city>
<city>延庆区</city>
</province></root>`;
//创建文档对象
var parser=new DOMParser();
var xmlDoc=parser.parseFromString(str,"text/xml");
//提取数据
var countrys = xmlDoc.getElementsByTagName('city');
var arr = [];
//输出数据
for (var i = 0; i < countrys.length; i++) {
arr.push(countrys[i].textContent);
};
console.log(arr);
}

js解析本地xml文件

要解析的xml文件部分数据如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?xml version="1.0" encoding="utf-8"?>
<root>
<province name="北京直辖市">
<city>昌平区</city>
<city>朝阳区</city>
<city>崇文区</city>
<city>大兴区</city>
<city>东城区</city>
<city>房山区</city>
<city>丰台区</city>
<city>海淀区</city>
<city>怀柔区</city>
<city>门头沟区</city>
<city>密云区</city>
<city>平谷区</city>
<city>石景山区</city>
<city>顺义区</city>
<city>通州区</city>
<city>西城区</city>
<city>宣武区</city>
<city>延庆区</city>
</province>
<province name="上海直辖市">
<city>宝山区</city>
<city>长宁区</city>
<city>崇明县</city>
<city>奉贤区</city>
<city>虹口区</city>
<city>黄浦区</city>
<city>嘉定区</city>
<city>金山区</city>
<city>静安区</city>
<city>卢湾区</city>
<city>闵行区</city>
<city>南汇区</city>
<city>浦东新区</city>
<city>普陀区</city>
<city>青浦区</city>
<city>松江区</city>
<city>徐汇区</city>
<city>杨浦区</city>
<city>闸北区</city>
</province>
</root>

解析内容放到二维数组中,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
if (window.XMLHttpRequest)
{ // code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{ // code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("GET","example.xml",false);
xmlhttp.send();
xmlDoc=xmlhttp.responseXML;
console.log(xmlDoc);
var arr=[];
var x=xmlDoc.getElementsByTagName("province");
var arr=new Array(x.length);
Array.from(x).forEach( function(el, index) {
if(arr[index]==undefined){
arr[index]=[];
}
Array.from(el.getElementsByTagName("city")).forEach(function (e,i) {
arr[index].push(e.childNodes[0].nodeValue);
})
});
console.log(arr);

  • open方法三个参数分别为http请求方式、请求地址、同步(false,阻塞,不使用异步)还是异步(true);
  • send方法用于post传递参数,本例未用到,默认为null。如xmlhttp.send(“data=data&data2=data2”);
  • responseXML属性返回XML文档对象;
  • xmlDoc.getElementsByTagName得到的是Dom对象,不可使用forEach,使用Array.from(x)创建数组实例;
  • Array.from()的参数为类似数组或者可迭代的对象,只要有length属性的方法均可作为参数;

js解析ajax请求返回的文档对象

使用jquery的ajax方法,将返回对象解析到json中,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>解析xml文件</title>
<script src="http://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.js">
</script>
</head>
<body>
</body>
<script>
console.log('****************************************************************');
$.ajax({
type: "GET",
url: "https://pay.heepay.com/API/PayTransit/QueryProvincesAndCities.aspx",
dataType: "xml",
success: function (ResponseText) {
var json={};
Array.from(ResponseText).forEach( function(el, index) {
if(json[el.getAttribute('name')]==undefined){
json[el.getAttribute('name')]=[];
}
Array.from(el.getElementsByTagName("city")).forEach(function (e,i) {
json[el.getAttribute('name')].push(e.childNodes[0].nodeValue);
})
});
console.log(json);
}
});
</script>
</html>

控制台查看返回如下,跨域,不可访问。

1
2
XMLHttpRequest cannot load
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

而用java,httpClient请求(用的Apache HttpClient 4.5.2),可以拿到该资源。浏览器输入网址可以访问,用postMan也可访问,唯有ajax不可访问。于是查了下,才想起来浏览器的同源策略导致Ajax只能同源使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpOptions;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
public class TestMain
{
public static void main(String[] args){
String url = "https://pay.heepay.com/API/PayTransit/QueryProvincesAndCities.aspx";
String result = doGet(url);
System.out.println(result);
}
public static String doGet(String url)
{
CloseableHttpClient httpclient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String result = "";
HttpGet httpGet = new HttpGet(url);
try
{
response = httpclient.execute(httpGet);
if (response.getStatusLine().getStatusCode() == 200)
{
HttpEntity entity = response.getEntity();
result = EntityUtils.toString(entity);
EntityUtils.consume(entity);
}
}
catch (Exception e)
{
e.getStackTrace();
}
finally
{
try
{
if (response != null)
response.close();
httpclient.close();
}
catch (IOException e)
{
}
}
return result;
}
}

浏览器的同源安全策略

同源安全策略是浏览器最核心也是最基本的安全机制。
同源策略限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的关键安全机制,为了保证用户信息的安全,防止恶意的网站窃取数据。
比如A网站设置的 Cookie,由于同源策略,B网站就不能打开或修改。设想如下情况:A网站是一家银行,用户登录以后,又去浏览其他网站。如果其他网站可以读取A网站的 Cookie,信息就会泄漏,其他网站就可以冒充用户,为所欲为。
同源的定义:

  • 协议相同
  • 域名相同
  • 端口相同

跨域需要双端协作,本文用的接口没有服务端控制权,只有前端单方面无法解决跨域问题,ajax不可请求该资源。