我想验证给定的html表语法是否正确,关于所有colspan和rowspan定义。
下表在语法上是正确的:
<table id="correct">
<tr>
<td>a</td>
<td>b</td>
<td rowspan="2">c</td>
</tr>
<tr>
<td colspan="2">d</td>
</tr>
</table>
下一个表格错误,因为列和行都不匹配:
<table id="wrong1">
<tr>
<td>a</td>
<td>b</td>
<td rowspan="1">c</td>
</tr>
<tr>
<td colspan="1">d</td>
</tr>
</table>
我希望能够验证表是正确还是错误。给定的代码只是一个示例,无论其复杂程度如何,它都应该使用任何给定的表进行验证。
我可以开始编写自己的验证器,但在此之前我想知道是否有任何库或已经有效的解决方案。你能帮我解决这个问题吗?
/修改
刚刚找到这个在线验证员:
http://wet-boew.github.com/wet-boew/demos/tableparser/validator-htmltable.html
我的第一个错误的表#wrong1
会引发错误,但#wrong2
没有错误(请参阅fiddle)。似乎它不支持太大的数字。
答案 0 :(得分:1)
你去,这是一个有效的代码:
function validateTable(id){
var rows = document.getElementById(id).tBodies[0].rows;
var totalCells=0;
// total rows and columns
var totalRows=rows.length;;
var totalColumns=0;;
var foundCells=new Array();
var maxRows=rows.length;
var maxColumns=0;
var maxCellIndex = 0;
// First we get totalRows and totalColumns
for(var i=0;i<rows.length;i++){
totalColumns = Math.max(totalColumns,rows[i].cells.length);
}
// The matrix now should be totalRows x totalColumns
for(var i=0;i<totalRows;i++){
for(var j=0;j<totalColumns;j++){
maxCellIndex = (i*totalColumns)+j;
foundCells[ maxCellIndex ] = 0;
}
}
for(var i=0;i<rows.length;i++){
maxColumns = Math.max(rows[i].cells.length,maxColumns);
for(var j = 0;j<rows[i].cells.length;j++){
var cellPosition = (i*totalColumns)+j;
var cols=0;
var tcells=0;
cols = parseInt( rows[i].cells[j].rowSpan );
tcells = parseInt( rows[i].cells[j].colSpan );
if(tcells>0){
for(var k=0;k<tcells;k++){
foundCells[cellPosition + k] = 1;
}
}
if(cols > 0){
for(var k=0;k<cols;k++){
foundCells[cellPosition + (k*totalColumns) ] = 1;
}
}
// totalCells += ( tcells * cols) ;
}
}
// This is the updated part
var allCellsAlignedCorrectly=true;
for(var n=0;n<=maxCellIndex;n++){
if(isNaN(foundCells[n]) || parseInt(foundCells[n]) == 0){
allCellsAlignedCorrectly = false;
}
}
for(var n=0;n<=foundCells.length;n++){
if(!isNaN(foundCells[n])){
totalCells+=foundCells[n];
}
}
// alert(foundCells);
// alert(totalCells+":"+totalColumns+":"+totalRows);
return (((totalCells) == (maxRows*maxColumns)) && allCellsAlignedCorrectly);
}
再次更新再次检查
你可以在这里看到它:
答案 1 :(得分:1)
根据Shehabix的答案,我重写了验证器。主要改进:
(请参阅开发者控制台获取输出)
<强>的JavaScript 强>
function validateTable(id){
console.log('[validating table #' + id + ']');
var rows = document.getElementById(id).tBodies[0].rows;
var hasErrors = false;
// total rows and columns
var totalRows = rows.length;
var totalColumns= 0;
for(var row=0; row<rows.length; row++) {
var cells = rows[row].cells;
var cols = 0;
for(var col=0; col<cells.length; col++) {
var cell = rows[row].cells[col];
var colspan = parseInt(cell.colSpan);
if(colspan > 1) {
cols += colspan;
} else {
cols++;
}
}
totalColumns = Math.max(totalColumns, cols);
}
var cells = {};
cells.init = function(row, col, options) {
cells[row + ':' + col] = $.extend({
row: row,
col: col,
count: 0
}, options);
}
cells.update = function(row, col, options) {
var cell = cells[row + ':' + col];
if(!cell) {
hasErrors = true;
console.log('cell outside of table dimensions (cell ' + (row+1) + ':' + (col+1) + ' is outside of allowed table size ' + totalRows + ':' + totalColumns + ')');
return;
}
cells[row + ':' + col].count++;
if(options) {
cells[row + ':' + col] = $.extend(cells[row + ':' + col], options);
}
}
cells.get = function(row, col) {
return cells[row + ':' + col];
}
var colspans = {};
colspans.add = function(row, col, count) {
for(var coladd=0; coladd<count; coladd++) {
colspans[row + ':' + (col+coladd)] = true;
}
};
colspans.check = function(row, col) {
return colspans[row + ':' + col];
};
var rowspans = {};
rowspans.add = function(row, col, count) {
for(var rowadd=0; rowadd<count; rowadd++) {
rowspans[(row+rowadd) + ':' + col] = true;
}
};
rowspans.check = function(row, col) {
return rowspans[row + ':' + col];
};
// init cell matrix
for(var row=0; row<totalRows; row++) {
for(var col=0; col<totalColumns; col++) {
cells.init(row, col);
}
}
for(var row=0; row<rows.length; row++) {
var colskip = 0;
var rowskip = 0;
for(var col=0; col<totalColumns; col++) {
// check if this cell is pushed by a colspan
if(colspans.check(row, col)) continue;
// check if this cell is pushed by a rowspan
if(rowspans.check(row, col)) {
rowskip++;
continue;
}
console.log("row: " + row + " - col: " + (col-colskip-rowskip));
var cell = rows[row].cells[col-colskip-rowskip];
if(!cell) continue;
var rowspan = parseInt(cell.rowSpan);
var colspan = parseInt(cell.colSpan);
cells.update(row, col, {
element: cell
});
if(colspan > 1){
colskip += colspan-1;
colspans.add(row, col+1, colspan-1);
for(var coladd=1; coladd<colspan; coladd++) {
cells.update(row, col+coladd, {
element: cell
});
}
}
if(rowspan > 1){
rowspans.add(row+1, col, rowspan-1);
for(var rowadd=1; rowadd<rowspan; rowadd++) {
cells.update(row+rowadd, col, {
element: cell
});
}
}
}
}
for(var row=0; row<totalRows; row++) {
for(var col=0; col<totalColumns; col++) {
var cell = cells.get(row, col);
if(cell.count == 1) {
// everything is fine
} else if(cell.count == 0) {
hasErrors = true;
console.log("cell " + (row+1) + ':' + (col+1) + " is missing");
} else {
hasErrors = true;
console.log("cell " + (row+1) + ':' + (col+1) + " is overlapping with rowspan (cell usage count of " + cell.count + ")");
}
}
}
console.log('table is ' + (hasErrors ? 'invalid' : 'valid'));
return hasErrors;
}
-