# aardio 范例: 简单 XML 解析

```aardio
//简单 XML 解析
import string.xml;
import console;

var xmlstr =  /*
<?xml version="1.0" encoding="utf-8"?>
<project ver="10" name="aardio工程3" libEmbed="true" icon="...">
<file name="main" path="main.aardio" > 
</file>
<folder name="资源文件" path="res" embed="true">
<![CDATA[ 
<folder name="资源文件" path="res" embed="true">
]]>
</folder>
<folder name="库" path="lib">
</folder>
<abc />
</project> 
*/

var xmlDoc = string.xml( xmlstr )
 
/*
xmlDoc 是一个表对象。
在这个表对象里所有的 XML 节点都是一个表对象。

节点对象可能具有 3 类元素：
1. 节点的属性存储为名值对成员，键值都是字符串。 
2. 所有相同标签名的子节点也存储为名值对成员，键为标签名，值为子节点数组。
3. 节点对象的数组成员存储了全部子节点。  

XML 节点对象分为 4 类：

1. 拥有标签名（ tagName 属性）的普通 XML 元素 
2. string.xml 总是虚拟出一个空的没有 tagName 属性的顶层根节点。 
3. 文本节点：使用 text 属性表示文本,无 tagName 属性
4. CDATA节点：使用 cdata 属性表示数据, 无 tagName 属性
	
上面的 xmlDoc 表示根节点。
xmlDoc[1] 表示第一个子节点。
xmlDoc.project[1] 表示第一个 project 子节点。
xmlDoc.project[1].folder[1] 表示第 1 个 project 子节点的第 1 个 folder 子节点。
*/

//直接返回第 1 个标签名为 project 的子节点
var firstProject = xmlDoc.project[1];

/*
xmlDoc.queryEles 搜索所有符合条件的子节点（递归搜索所有下级节点，不仅仅搜索子节点）
参数是一个表对象，可以指定一个或多个属性名值对以查询所有匹配的节点。
返回值是纯数组。
*/
var projects = xmlDoc.queryEles( tagName = "project");  

var firstProject = projects[1];

//这样遍历的是所有元素（）而不仅仅是子节点
for(k,any in firstProject){
	// any可能是名字为 k 的属性值、标签名为 k 的子节点数组、数值索引为 k 的子节点
}

//仅遍历子节点数组
for(i=1;#firstProject;1){
	var childNode = firstProject[i]
	console.log(i,childNode) 
}

console.clearScreen()

/*
也可以调用节点的 eachChild 方法创建迭代器以遍历子节点，
可选用参数 1 指定要搜索的标签名（ tagName ），标签名忽略大小写，忽略命名空间前缀
*/
for(i,localTagName,childCount,xNode in firstProject.eachChild("folder") ){

	console.log(i,tagName)
	console.dump(xNode);
	
	console.log( 
		i, //数组索引
		localTagName,//标签名（去掉命名空间前缀）
		childCount, //xNode拥有的子节点数目
		xNode.outerXml() //节点 XML，直接写 
	) 
	
	/*
	注意 outerXml,innerXml,innerText 可作为方法也可以作为属性使用。
	直接写 xNode.outerXml 返回的是 XML 而非函数对象，等价于调用 xNode.outerXml()
	*/
}
 
console.pause()
```