我有很多筆下面那樣的資料
<mane01>0</mane>
<type>text</type>
<title>01</title>
<mane02>1</mane>
<type>text</type>
<title>02</title>
<mane03>2</mane>
<type>val</type>
<title>03</title>
他們被寫在同一個xml裡,我利用下面方法抓取該xml中的類型
var miscellaneous = new HandleXml();
Info.setUrl("../xml/text.xml");
var InfoInfo = Info.getNodeValue("type");
我需要將同類型的title顯示在ID=se的select中供選擇
<select id="se"></select>
目前我只會抓單筆,但我最終結果需要抓多筆,請問我能怎麼做?
我把樓主的xml格式稍作修改如下:
01.xml
<manes>
<mane>
<mindex>0</mindex>
<type>text0</type>
<title>01</title>
</mane>
<mane>
<mindex>1</mindex>
<type>text1</type>
<title>02</title>
</mane>
<mane>
<mindex>2</mindex>
<type>text2</type>
<title>03</title>
</mane>
</manes>
再來是html+javascript的部份,這邊有用到jquery處理load xml file & parsing:
test.htm
<!doctype html>
<html><head>
<meta charset="utf-8">
<title>jQuery讀取xml並轉陣列或直接處理</title>
<script
src="https://code.jquery.com/jquery-3.4.0.min.js"
integrity="sha256-BJeo0qm959uMBGb65z40ejJYGSgR7REI4+CW1fNKwOg="
crossorigin="anonymous"></script>
</head>
<body>
<label>Manes:</label><select id="se"></select>
<script>
var tmpIndex=[], tmpType=[], tmpTitle=[]; //這行非必要只是測試把xml內容塞入陣列
var tmpOptionStr='';
$.ajax({
url: './01.xml',
type: 'GET',
dataType: 'xml',
success: function(returnedXMLResponse){
$('mane', returnedXMLResponse).each(function(){
tmpIndex.push($('mindex', this).text()); //這行非必要只是測試把xml內容塞入陣列
tmpType.push($('type', this).text()); //這行非必要只是測試把xml內容塞入陣列
tmpTitle.push($('title', this).text()); //這行非必要只是測試把xml內容塞入陣列
tmpOptionStr+='<option value="'+$('mindex', this).text()+'">'+$('title', this).text()+' '+$('type', this).text()+'</option>';
});
console.log(tmpOptionStr);
$('#se').html(tmpOptionStr);
}
});
</script>
</body>
</html>
var tmpIndex=[], tmpType=[], tmpTitle=[];
tmpIndex.push($('mindex', this).text());
tmpType.push($('type', this).text());
tmpTitle.push($('title', this).text());
這四行沒有也沒關係,只是順便列出把xml轉成陣列的方式給樓主參考,轉成陣列後要用迴圈抓內容就是桌上抓橘的事了,例如:
for(var i=0;i<tmpIndex.length;i++){
tmpStr+='<option value="'+tmpIndex[i]+'"'>+tmpTitle[i]+' '+tmpTitle[i]+'</option>';
}
提外話,如果可以的話把xml內容格式改成json會更好,以01.xml內容為例,轉成01.json變成:
{{'mindex':0,'type':'text0','title:'01'},{'mindex':1,'type':'text1','title:'02'},{'mindex':2,'type':'text2','title:'03'}}
對enduser來說同樣的內容,下載檔案size卻小很多,當然改用json存取的方式要改寫,但不會很難就是了,提供您參考。
<manes>
<mane1>
<mindex>0</mindex>
<type>text</type>
<title>01</title>
</mane1>
<mane2>
<mindex>1</mindex>
<type>text</type>
<title>02</title>
</mane2>
<mane3>
<mindex>2</mindex>
<type>id</type>
<title>03</title>
</mane3>
</manes>
嚴格來說應該會是這樣的形態,type會有重複的,我要顯示一樣type的title,但我目前寫的都會全部顯示
那個標籤本來就不應該這樣寫
<mane01>...</mane01>
<mane02>...</mane02>
要改成
<mane>...<title>01</title></mane>
<mane>...<title>02</title></mane>
這樣才有辦法去取得所有<mane>裡面的東西,
寫成<mane+遞增數字>應該還是有辦法,但是不建議,因為那是繞遠路的作法,你應該做的是改寫產出xml的程式,讓它排列出適用的格式。
"嚴格來說應該會是這樣的形態,type會有重複的,我要顯示一樣type的title,但我目前寫的都會全部顯示"
這個我看不太懂你說的意思,能附個圖片描述嗎?
xml的內容我這邊無法做修改,那是FW做出來的結果,所以才會比較麻煩,如果必須要繞遠路的話我也只能繞了
而"嚴格來說應該會是這樣的形態,type會有重複的,我要顯示一樣type的title,但我目前寫的都會全部顯示"拿我上面第一個留言的內容來說就是指有3筆資料,但我只顯示type為text的資料或者type為id的資料這樣,但我做出來的結果都與大大你做出來的結果一樣是全部都顯示。
FW是什麼?
全部都顯示是因為我沒設過濾條件啊(就是單純把全部節點跑一遍),
你寫的:”我要顯示一樣type的title”,
我還是看不懂,是type都等於"text"的列出來還是type要等於什麼呢,
有明確的定義才有辦法設過濾條件。_。
作了一點點改寫 加上判斷如果type=="text"就會在第一個select裡,如果不是就會在第二個select裡,這樣是類似你要的結果嗎?
test.htm
<!doctype html>
<html><head>
<meta charset="utf-8">
<title>jQuery讀取xml並轉陣列或直接處理</title>
<script
src="https://code.jquery.com/jquery-3.4.0.min.js"
integrity="sha256-BJeo0qm959uMBGb65z40ejJYGSgR7REI4+CW1fNKwOg="
crossorigin="anonymous"></script>
</head>
<body>
<label>Manes_TEXT:</label><select id="seType"></select>
<label>Manes_ID:</label><select id="seId"></select>
<script>
var tmpStrType='',tmpStrId='';
$.ajax({
url: './01.xml',
type: 'GET',
dataType: 'xml',
success: function(returnedXMLResponse){
$('mane', returnedXMLResponse).each(function(){
if($('type', this).text()=='text'){
tmpStrType+='<option value="'+$('mindex', this).text()+'">'+$('title', this).text()+' '+$('type', this).text()+'</option>';
}else{
tmpStrId+='<option value="'+$('mindex', this).text()+'">'+$('title', this).text()+' '+$('type', this).text()+'</option>';
}
});
$('#seType').html(tmpStrType);
$('#seId').html(tmpStrId);
}
});
</script>
</body>
</html>
01.xml
<manes>
<mane>
<mindex>0</mindex>
<type>text</type>
<title>01</title>
</mane>
<mane>
<mindex>1</mindex>
<type>text</type>
<title>02</title>
</mane>
<mane>
<mindex>2</mindex>
<type>id</type>
<title>03</title>
</mane>
</manes>
<type></type>
內的文字不一樣,像下面這段中的<type></type>
內的文字內容有text跟id,mane也並非是<mane></mane>
這樣,而是<mane1></mane1>
、<mane2></mane2>
...這樣的寫法
<manes>
<mane1>
<mindex>0</mindex>
<type>text</type>
<title>01</title>
</mane1>
<mane2>
<mindex>1</mindex>
<type>text</type>
<title>02</title>
</mane2>
<mane3>
<mindex>2</mindex>
<type>id</type>
<title>03</title>
</mane3>
</manes>
而我想做的是將xml中所有資料中<type></type>
內容一樣的資料顯示出來
var Info = new HandleXml();
Info.setUrl("../test.xml");
var x = Info.getNodeValue("type");
if(x == "text"){
...//show資料
} //這判斷式用在mane後未加編號時
是的,大大後來寫的code類似我要的結果,非常感謝您。
剛剛忘了還有一個問題,<mane></mane>
部分若是mane+編號的話$('mane', returnedXMLResponse).each(function(){...}
部分我該怎麼改??在外層加與for(var a=0; a<tmpIndex.length; a++){...}
類似的迴圈就好嗎?
修改好的demo您參考看看:
大部份都沒有改到,主要是在讀入xml時,把xml轉成str,然後用RegExp把<mane數字></mane數字>置換成<mane></mane>,再把處理好的str轉成xml物件...以下略。
test.htm
<!doctype html>
<html><head>
<meta charset="utf-8">
<title>jQuery讀取xml並轉陣列或直接處理</title>
<script
src="https://code.jquery.com/jquery-3.4.0.min.js"
integrity="sha256-BJeo0qm959uMBGb65z40ejJYGSgR7REI4+CW1fNKwOg="
crossorigin="anonymous"></script>
</head>
<body>
<label>Manes_TEXT:</label><select id="seType"></select>
<label>Manes_ID:</label><select id="seId"></select>
<script>
function xmlToString(xmlData) {
var xmlString;
//IE
if (window.ActiveXObject){
xmlString = xmlData.xml;
}
else{
xmlString = (new XMLSerializer()).serializeToString(xmlData);
}
return xmlString;
}
var tmpStrType='',tmpStrId='';
$.ajax({
url: './01.xml',
type: 'GET',
dataType: 'xml',
success: function(returnedXMLResponse){
xmlStr=xmlToString(returnedXMLResponse);
console.log('原本的xml內容:\n'+xmlStr);
xmlStr=xmlStr.replace(/mane\d{1,2}>/g, "mane>");
console.log('\n修改標籤後的xml內容:\n'+xmlStr);
newXml=$.parseXML(xmlStr);
$('mane', newXml).each(function(){
if($('type', this).text()=='text'){
tmpStrType+='<option value="'+$('mindex', this).text()+'">'+$('title', this).text()+' '+$('type', this).text()+'</option>';
}else{
tmpStrId+='<option value="'+$('mindex', this).text()+'">'+$('title', this).text()+' '+$('type', this).text()+'</option>';
}
});
$('#seType').html(tmpStrType);
$('#seId').html(tmpStrId);
}
});
</script>
</body>
</html>
01.xml
<manes>
<mane1>
<mindex>0</mindex>
<type>text</type>
<title>01</title>
</mane1>
<mane2>
<mindex>1</mindex>
<type>text</type>
<title>02</title>
</mane2>
<mane3>
<mindex>2</mindex>
<type>id</type>
<title>03</title>
</mane3>
</manes>
1.用迴圈,重複抓一筆資料直到全部抓完
2.透過jQuery
jQuery教學-jQuery讀取XML整合與應用
jQuery parsing XML: get an element with a specific attribute
為了練習一下JS寫的。
xml可以讓browser去解析,應該不用用到regex。
然後其實用JQ搞不好更快。
chrome、firefox等現代瀏覽器only。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<select id="text-select"></select>
</body>
</html>
<script>
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// 去除掉純文字節點
var manes = Array.from(this.responseXML.querySelector("manes").childNodes).filter(elm => elm.nodeName != "#text")
// 將節點轉換成JSON
var result = manes.map(function(elm){
var children = Array.from(elm.childNodes).filter(elm => elm.nodeName != "#text")
var temp = {}
for (var child of children){
temp[child.nodeName] = child.innerHTML
}
return temp
})
// 對array內每個object處理,產生option
result.filter(o => o.type == "text").map(o => {
var select = document.getElementById("text-select")
var option = document.createElement("option")
option.innerText = o.title
option.setAttribute("mindex", o.mindex)
select.appendChild(option)
})
}
};
xhttp.open("GET", "./01.xml", true);
xhttp.send();
</script>