VML树形显示XML
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
<?xml version="1.0" encoding="GB2312"?>
<公司>
<总经理>
<部门A经理>
<职员A1 />
<职员A2 />
<职员A3 />
</部门A经理>
<部门B经理>
<职员B1 />
<职员B2 />
<职员B3 />
</部门B经理>
<部门C经理>
<职员C1 />
<职员C2 />
<职员C3 />
</部门C经理>
</总经理>
</公司>
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
<html xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<META HTTP-EQUIV="MSThemeCompatible" CONTENT="Yes">
<style type="text/css">
v\:*{
behavior:url(#default#VML);
}
v\:RoundRect{
text-align:center;
position:relative;
}
v\:TextBox{
vertical-align:middle;
font-size:13px;
}
</style>
<script type="text/javascript">
function $(id){
return document.getElementById(id);
}
function Point2D(x,y){
this.x = x;
this.y = y;
}
function Xml2Vml(xmlFile){
this.XML = new ActiveXObject("MSXML2.DOMDocument.5.0");
this.XML.async=false;
this.XML.load(xmlFile);
this.SpanX = 10;
this.SpanY = 25;
this.ItemWidth = 100;
this.ItemHeight = 25;
this.VmlRoot = document.createElement('<v:group coordsize="1000,1000" id="vml" style="width:1000px;height:1000px;">');
}
Xml2Vml.prototype.RecursiveParse = function(rootNode,offset){
var allChild = rootNode.childNodes;
var xOffset = offset.x;
var yOffset = offset.y;
if(allChild.length==0){
rootNode.setAttribute("LeftX",xOffset);
rootNode.setAttribute("RightX",xOffset+this.ItemWidth);
xOffset += this.SpanX + this.ItemWidth;
}else{
for(var i=0;i<allChild.length;i++){
var w = this.RecursiveParse(allChild[i],new Point2D(xOffset,yOffset+2*this.SpanY+this.ItemHeight));
xOffset += this.SpanX + w;
}
rootNode.setAttribute("LeftX",(parseInt(allChild[0].getAttribute("LeftX")) + parseInt(allChild[0].getAttribute("RightX")))/2);
rootNode.setAttribute("RightX",(parseInt(allChild[allChild.length-1].getAttribute("LeftX")) + parseInt(allChild[allChild.length-1].getAttribute("RightX")))/2);
}
rootNode.setAttribute("PosY",yOffset);
return xOffset-offset.x-this.SpanX;
}
Xml2Vml.prototype.ParseXml = function(){
this.RecursiveParse(this.XML.documentElement,new Point2D(0,0));
}
Xml2Vml.prototype.RecursiveRender = function(xmlNode){
var allChild = xmlNode.childNodes;
var xl = xmlNode.getAttribute("LeftX");
var xr = xmlNode.getAttribute("RightX");
var x = (parseInt(xl)+parseInt(xr))/2;
var y = xmlNode.getAttribute("PosY");
var str = xmlNode.tagName;
if(xmlNode!=this.XML.documentElement) this.VmlRoot.appendChild(document.createElement('<v:line from="'+x+','+y+'" to="'+x+','+(parseInt(y)+this.SpanY)+'" />'));
y=parseInt(y)+this.SpanY;
var RoundRect = document.createElement('<v:RoundRect style="width:'+this.ItemWidth+'px;height:'+this.ItemHeight+'px;left:'+(x-this.ItemWidth/2)+'px;top:'+y+'px" align="center">')
RoundRect.appendChild(document.createElement('<v:shadow on="True" type="single" color="#b3b3b3" offset="5px,5px"/>'));
var TextBox = document.createElement('<v:TextBox />');
TextBox.innerHTML = str;
RoundRect.appendChild(TextBox);
this.VmlRoot.appendChild(RoundRect);
if(allChild.length>0){
y += this.ItemHeight+this.SpanY;
this.VmlRoot.appendChild(document.createElement('<v:line from="'+x+','+(y-this.SpanY)+'" to="'+x+','+y+'" />'));
xl = (parseInt(allChild[0].getAttribute("LeftX")) + parseInt(allChild[0].getAttribute("RightX")))/2;
xr = (parseInt(allChild[allChild.length-1].getAttribute("LeftX")) + parseInt(allChild[allChild.length-1].getAttribute("RightX")))/2;
this.VmlRoot.appendChild(document.createElement('<v:line from="'+xl+','+y+'" to="'+xr+','+y+'" />'));
for(var i=0;i<allChild.length;i++) this.RecursiveRender(allChild[i]);
}
}
Xml2Vml.prototype.RenderVml = function(){
this.RecursiveRender(this.XML.documentElement);
}
</script>
</head>
<body>
<center>
<div id="div" style="WIDTH: 1000px; HEIGHT: 1000px"></div>
</center>
<script type="text/javascript">
var Ins = new Xml2Vml("data.xml");
Ins.ParseXml();
Ins.RenderVml();
$("div").appendChild(Ins.VmlRoot);
</script>
</body>
</html>
输出结果: