让你的Mozilla支持XML数据岛
由于Mozilla没有内建的机制支持XML数据岛,但是Mozilla提供了对DOM的支持,我们可以通过DOM访问XML数据岛中节点、属性等。 下面就是一个比较全面的例子:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<style type="text/css">
XML
{
WIDTH: 0px;
HEIGHT: 0px;
DISPLAY: none;
}
</style>
<script language="JavaScript">
<!-- <![CDATA[
function setEvents() {
MozillaDSO();
}
function showDSO() {
if(window.navigator.appName=="Microsoft Internet Explorer")
{
alert(xmlOne.XMLDocument.xml)
alert(xmlTwo.XMLDocument.xml)
}
else
{
for(var i=0;i < document.getElementsByTagName('xml').length;i++)
alert(document.getElementsByTagName('xml').item(i).innerHTML);
}
}
function MozillaDSO() {
/* Function: MozillaDSO
Creation Date: April 16, 2003
Programmer: Edmond Woychowsky
Purpose: The purpose of this function is to perform binding of
XML Data Islands for Mozilla. The logic herein is bypassed
for Microsoft Internet Explorer.
Update Date: Programmer: Description:
*/
// Global variables
objXMLDI = new collection(); // XML data island collection
objBound = new collection(); // Bound XHTML object collection
// Local variables
var objDatafld; // Table datafld collection
var objRow; // Table row
var reWork = new RegExp('internet explorer','gi');
var arrKeys = new Array();
var intKey = 0; // objBound collection key
var intRows; // Row count
if(!reWork.test(navigator.appName)) {
// Locate data islands
for(var i=0;i < document.getElementsByTagName('xml').length;i++)
objXMLDI.add('#' + document.getElementsByTagName('xml').item(i).getAttribute('id'),document.getElementsByTagName('xml').item(i));
// Locate bound nodes
for(var i=0;i < document.getElementsByTagName('table').length;i++)
if(document.getElementsByTagName('table').item(i).getAttribute('datasrc') != null) {
objBound.add(intKey.toString(),new boundXML());
objBound.item(intKey.toString()).datasrc = document.getElementsByTagName('table').item(i).getAttribute('datasrc');
objBound.item(intKey.toString()).node = document.getElementsByTagName('table').item(i);
objBound.item(intKey.toString()).nodeName = document.getElementsByTagName('table').item(i).nodeName;
objDatafld = new collection(); // Reset collection;
intRows = 0; // Reset row count
// Remove all rows
if(objBound.item(intKey.toString()).node.getElementsByTagName('tr').length != 0) {
for(var j=0;j < objBound.item(intKey.toString()).node.getElementsByTagName('tr').length;j++)
objRow = objBound.item(intKey.toString()).node.lastChild.removeChild(objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j));
for(var j=0;j < objBound.item(intKey.toString()).node.getElementsByTagName('tr').length;j++)
objRow = objBound.item(intKey.toString()).node.lastChild.removeChild(objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j));
}
// Determine bound nodes
for(var j=0;j < objRow.getElementsByTagName('input').length;j++)
if(!objDatafld.exists(objRow.getElementsByTagName('input').item(j).getAttribute('datafld')))
objDatafld.item(objRow.getElementsByTagName('input').item(j).getAttribute('datafld'),null);
for(var j=0;j < objRow.getElementsByTagName('div').length;j++)
if(!objDatafld.exists(objRow.getElementsByTagName('div').item(j).getAttribute('datafld')))
objDatafld.item(objRow.getElementsByTagName('div').item(j).getAttribute('datafld'),null);
for(var j=0;j < objRow.getElementsByTagName('span').length;j++)
if(!objDatafld.exists(objRow.getElementsByTagName('span').item(j).getAttribute('datafld')))
objDatafld.item(objRow.getElementsByTagName('span').item(j).getAttribute('datafld'),null);
arrKeys = objDatafld.keys();
// Determine row count
for(var j=0;j < arrKeys.length;j++)
if(intRows < objXMLDI.item(objBound.item(intKey.toString()).datasrc).getElementsByTagName(arrKeys[0]).length)
intRows = objXMLDI.item(objBound.item(intKey.toString()).datasrc).getElementsByTagName(arrKeys[0]).length;
for(var j=0;j < intRows;j++)
objBound.item(intKey.toString()).node.lastChild.appendChild(objRow.cloneNode(true));
// Rebuild table and bind
for(var j=0;j < objBound.item(intKey.toString()).node.getElementsByTagName('tr').length;j++)
for(var k=0;k < objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').length;k++)
for(var l=0;l < objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.length;l++)
switch(objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).nodeName.toLowerCase()) {
case('input'):
try {
if(objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('type') != 'checkbox')
objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).value = objXMLDI.item(objBound.item(intKey.toString()).datasrc).getElementsByTagName(objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('datafld')).item(j).firstChild.nodeValue;
else
objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).checked = eval(objXMLDI.item(objBound.item(intKey.toString()).datasrc).getElementsByTagName(objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('datafld')).item(j).firstChild.nodeValue);
}
catch(e) { }
if(objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('type') != 'checkbox')
objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).onchange = new Function('try { objXMLDI.item(\'' + objBound.item(intKey.toString()).datasrc + '\').getElementsByTagName(\'' + objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('datafld') + '\').item(' + j.toString() + ').firstChild.nodeValue = this.value } catch(e) { objXMLDI.item(\'' + objBound.item(intKey.toString()).datasrc + '\').getElementsByTagName(\'' + objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('datafld') + '\').item(' + j.toString() + ').appendChild(document.createTextNode(this.value)) };MozillaDSO;');
else
objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).onchange = new Function('try { objXMLDI.item(\'' + objBound.item(intKey.toString()).datasrc + '\').getElementsByTagName(\'' + objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('datafld') + '\').item(' + j.toString() + ').firstChild.nodeValue = this.checked } catch(e) { objXMLDI.item(\'' + objBound.item(intKey.toString()).datasrc + '\').getElementsByTagName(\'' + objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('datafld') + '\').item(' + j.toString() + ').appendChild(document.createTextNode(this.checked)) };MozillaDSO;');
break;
case('div'):
case('span'):
try { // Text node exists
objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).firstChild.nodeValue = objXMLDI.item(objBound.item(intKey.toString()).datasrc).getElementsByTagName(objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('datafld')).item(j).firstChild.nodeValue;
}
catch(e) { // Create text node
try {
objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).appendChild(document.createTextNode(objXMLDI.item(objBound.item(intKey.toString()).datasrc).getElementsByTagName(objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('datafld')).item(j).firstChild.nodeValue));
}
catch(e) { }
}
break;
}
++intKey;
}
// Non-tabular datasrc/datafld
for(var i=0;i < document.getElementsByTagName('input').length;i++)
if(document.getElementsByTagName('input').item(i).getAttribute('datafld') != null) {
objBound.add(intKey.toString(),new boundXML());
if(document.getElementsByTagName('input').item(i).getAttribute('datasrc') != null)
objBound.item(intKey.toString()).datasrc = document.getElementsByTagName('input').item(i).getAttribute('datasrc');
objBound.item(intKey.toString()).datafld = document.getElementsByTagName('input').item(i).getAttribute('datafld');
objBound.item(intKey.toString()).node = document.getElementsByTagName('input').item(i);
objBound.item(intKey.toString()).nodeName = document.getElementsByTagName('input').item(i).nodeName;
++intKey;
}
for(var i=0;i < document.getElementsByTagName('div').length;i++)
if(document.getElementsByTagName('div').item(i).getAttribute('datafld') != null) {
objBound.add(intKey.toString(),new boundXML());
if(document.getElementsByTagName('div').item(i).getAttribute('datasrc') != null)
objBound.item(intKey.toString()).datasrc = document.getElementsByTagName('div').item(i).getAttribute('datasrc');
objBound.item(intKey.toString()).datafld = document.getElementsByTagName('div').item(i).getAttribute('datafld');
objBound.item(intKey.toString()).node = document.getElementsByTagName('div').item(i);
objBound.item(intKey.toString()).nodeName = document.getElementsByTagName('div').item(i).nodeName;
++intKey;
}
for(var i=0;i < document.getElementsByTagName('span').length;i++)
if(document.getElementsByTagName('span').item(i).getAttribute('datafld') != null) {
objBound.add(intKey.toString(),new boundXML());
if(document.getElementsByTagName('span').item(i).getAttribute('datasrc') != null)
objBound.item(intKey.toString()).datasrc = document.getElementsByTagName('span').item(i).getAttribute('datasrc');
objBound.item(intKey.toString()).datafld = document.getElementsByTagName('span').item(i).getAttribute('datafld');
objBound.item(intKey.toString()).node = document.getElementsByTagName('span').item(i);
objBound.item(intKey.toString()).nodeName = document.getElementsByTagName('span').item(i).nodeName;
++intKey;
}
arrKeys = objBound.keys();
// Handle non-tabular binds
for(var i=0;i < arrKeys.length;i++)
switch(objBound.item(arrKeys[i]).nodeName.toLowerCase()) {
case('table'):
objBound.item(arrKeys[i]).rows = new Array();
break;
case('input'):
try {
if(typeof(objBound.item(arrKeys[i]).datasrc) == 'string') {
try {
if(objBound.item(arrKeys[i]).node.getAttribute('type') != 'checkbox')
objBound.item(arrKeys[i]).node.value = objXMLDI.item(objBound.item(arrKeys[i]).datasrc).getElementsByTagName(objBound.item(arrKeys[i]).datafld).item(0).firstChild.nodeValue;
else
objBound.item(arrKeys[i]).node.checked = eval(objXMLDI.item(objBound.item(arrKeys[i]).datasrc).getElementsByTagName(objBound.item(arrKeys[i]).datafld).item(0).firstChild.nodeValue);
}
catch(e) { }
if(objBound.item(arrKeys[i]).node.getAttribute('type') != 'checkbox')
objBound.item(arrKeys[i]).node.onchange = new Function('try { objXMLDI.item(this.getAttribute(\'datasrc\')).getElementsByTagName(this.getAttribute(\'datafld\')).item(0).firstChild.nodeValue = this.value } catch(e) { objXMLDI.item(this.getAttribute(\'datasrc\')).getElementsByTagName(this.getAttribute(\'datafld\')).item(0).appendChild(document.createTextNode(this.value)) };MozillaDSO()');
else
objBound.item(arrKeys[i]).node.onclick = new Function('try { objXMLDI.item(this.getAttribute(\'datasrc\')).getElementsByTagName(this.getAttribute(\'datafld\')).item(0).firstChild.nodeValue = this.checked } catch(e) { objXMLDI.item(this.getAttribute(\'datasrc\')).getElementsByTagName(this.getAttribute(\'datafld\')).item(0).appendChild(document.createTextNode(this.checked)) };MozillaDSO()');
}
}
catch(e) { }
break;
case('div'):
case('span'):
if(typeof(objBound.item(arrKeys[i]).datasrc) == 'string') {
try { // Text node exists
objBound.item(arrKeys[i]).node.firstChild.nodeValue = objXMLDI.item(objBound.item(arrKeys[i]).datasrc).getElementsByTagName(objBound.item(arrKeys[i]).datafld).item(0).firstChild.nodeValue;
}
catch(e) { // Create text node
try {
objBound.item(arrKeys[i]).node.appendChild(document.createTextNode(objXMLDI.item(objBound.item(arrKeys[i]).datasrc).getElementsByTagName(objBound.item(arrKeys[i]).datafld).item(0).firstChild.nodeValue));
}
catch(e) { }
}
}
break;
default:
alert('Error: Unsupported HTML Element - ' + objBound.item(arrKeys[i]).nodeName.toLowerCase());
break;
}
}
function boundXML() {
var datasrc = null; // Data source (string)
var datafld = null; // Data field (string)
var node = null; // XHTML node (object)
var nodeName = null; // Node name (string)
}
}
function collection() {
/* Function: collection
Creation Date: August 16, 2002
Programmer: Edmond Woychowsky
Purpose: The purpose of this class is to define the collection
object associative array.
Update Date: Programmer: Description:
*/
// Properties
this.objcollection = new Object; // Associative array
this.count = 0; // Total numbers of items
// Methods
this.add = colAdd; // Add method
this.exists = colExists; // Exists method
this.item = colItem; // Item method
this.removeAll = colRemoveAll; // Remove all method
this.remove = colRemove; // Remove method
this.keys = colKeys; // Keys method
function colAdd(strKey,strItem) {
/* Function: colAdd
Creation Date: August 16, 2002
Programmer: Edmond Woychowsky
Purpose: The purpose of this function is to add an item to
the collection object.
Update Date: Programmer: Description:
*/
if(typeof(this.objcollection[strKey]) == 'undefined')
++this.count;
this.objcollection[strKey] = strItem;
}
function colExists(strKey) {
/* Function: colExists
Creation Date: August 16, 2002
Programmer: Edmond Woychowsky
Purpose: The purpose of this function is to return a boolean
indicating where or not a key exists in the
collection object.
Update Date: Programmer: Description:
*/
if(typeof(this.objcollection[strKey]) == 'undefined')
return false;
else
return true;
}
function colItem(strKey,strItem) {
/* Function: colItem
Creation Date: August 16, 2002
Programmer: Edmond Woychowsky
Purpose: The purpose of this function is to either set or get
an item to or from the collection object.
Update Date: Programmer: Description:
*/
if(typeof(strItem) == 'undefined')
return this.objcollection[strKey];
else {
if(typeof(this.objcollection[strKey]) == 'undefined')
++this.count;
this.objcollection[strKey] = strItem;
}
}
function colRemoveAll() {
/* Function: colRemoveAll
Creation Date: August 16, 2002
Programmer: Edmond Woychowsky
Purpose: The purpose of this function is to remove all keys
and items from the collection object and set the
item count to zero.
Update Date: Programmer: Description:
*/
this.objcollection = new Object;
this.count = 0;
}
function colRemove(strKey) {
/* Function: colRemove
Creation Date: August 16, 2002
Programmer: Edmond Woychowsky
Purpose: The purpose of this function is to remove a single
item and it's associated key from the collection
object and decrement the count by one.
Update Date: Programmer: Description:
*/
if(typeof(strItem) != 'undefined') {
this.objcollection[strKey] == 'undefined';
--this.count;
}
}
function colKeys() {
/* Function: colKeys
Creation Date: August 16, 2002
Programmer: Edmond Woychowsky
Purpose: The purpose of this function is to return an array
consisting of the collection object's keys.
Update Date: Programmer: Description:
*/
var arrWork = new Array();
var strKey;
for(strKey in this.objcollection)
if(this.objcollection[strKey] != 'undefined')
arrWork.push(strKey);
return arrWork;
}
}
// ]]> -->
</script>
</head>
<body οnlοad="setEvents()">
<table width="20%">
<tr>
<td>
<input type="text" id="input" datasrc="#xmlOne" datafld="first" />
</td>
</tr>
<tr>
<td>
<div id="div" datasrc="#xmlOne" datafld="second"></div>
</td>
</tr>
<tr>
<td>
<span id="span" datasrc="#xmlOne" datafld="third"></span>
</td>
</tr>
<tr>
<td>
<input type="checkbox" id="input" datasrc="#xmlOne" datafld="check" />
</td>
</tr>
</table>
<table datasrc="#xmlTwo" border="1">
<thead>
<td bgcolor="#FFFFEE">Line</td>
<td bgcolor="#FFFFEE">Word</td>
<td bgcolor="#FFFFEE">Color</td>
<td bgcolor="#FFFFEE">True/False</td>
</thead>
<tr>
<td>
<div datafld="line"></div>
</td>
<td>
<span datafld="word"></span>
</td>
<td>
<input type="text" id="input" datafld="color" />
</td>
<td>
<input type="checkbox" id="input" datafld="check" />
</td>
</tr>
</table>
<br />
<input type="button" οnclick="showDSO()" value="Show Data Islands" />
<xml id="xmlOne" async="false">
<root>
<first></first>
<second>plugh</second>
<third></third>
<check></check>
</root>
</xml>
<xml id="xmlTwo" async="false">
<root>
<row>
<line>1</line>
<word>one</word>
<color>red</color>
<check></check>
</row>
<row>
<line>2</line>
<word>two</word>
<color></color>
<check>false</check>
</row>
<row>
<line>3</line>
<word>three</word>
<color>blue</color>
<check>true</check>
</row>
</root>
</xml>
</body>
</html>