XML
可扩展标记语言
XML文档实例分析
CDATA部件
在CDATA内部的所有内容都会被解析器忽略。
如果文本包含了很多的”<”字符和”&”字符——就象程序代码一样,那么最好把他们都放到CDATA部件中。
一个 CDATA 部件以”
<![CDATA[
function matchwo(a,b)
{
if (a < b && a < 0) then
{
return 1
}
else
{
return 0
}
}
]]>```
## 实体
作用:避免重复输入 -- (宏、变量)
自定义实体语法:
<?xml version="1.0" encoding="GB2312"?>
<!DOCTYPE COMPANY [
<!ELEMENT COMPANY (NAME, ADDRESS)>
<!ELEMENT NAME (#PCDATA)>
<!ELEMENT ADDRESS (#PCDATA)>
<!ENTITY ent1 "实体1">
<!ENTITY ent2 "实体2">
]>
<!--this is a comment-->
<COMPANY>
<NAME>&ent1;&ent1;</NAME>
<ADDRESS>&ent2;</ADDRESS>
</COMPANY>```
## 格式正规的XML文档
- 语法规范
- 必须有XML声明语句
<?xml version="1.0" encoding="gb2312"?>
- 必须有且仅有一个根元素
- 标记大小写敏感
- 属性值用引号
- 标记成对
- 空标记关闭
- 元素正确嵌套
- 元素语法
- 名称中可以包含字母、数字或者其它字符
- 名称不能以数字和"_"(下划线)开头
- 名称中不能含空格
- 名称中不能含冒号(注:冒号留给命名空间使用)
## XML解析
### 文档对象模型(DOM):一种基于树结构的API
Students.xml
读取XML
- 使用 DocumentBuilder的 parse( ) 方法解析文件
- 将已解析的文档存储在 Document 使用 DOM 解析 XML 文档
- 获得一个新 DocumentBuilderFactory 实例
- 使用 DocumentBuilderFactory 构建 对象中
- 使用 getElementsByTagName( ) 方法获得元素
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
DocumentBuilder builder = null;
try {
builder=factory.newDocumentBuilder();
InputStream is = getResources().getAssets().open("fade_in.xml");
Document doc = builder.parse(is);
NodeList nl = doc.getElementsByTagName("alpha");
nl.item(0).setTextContent("test");
Source s = new DOMSource(doc);
StringWriter stringWriter = new StringWriter();
Result result = new StreamResult(stringWriter);
TransformerFactory factory1 = TransformerFactory.newInstance();
Transformer transformer = factory1.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.transform(s, result);
show.setText(stringWriter.getBuffer().toString());
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
- getDocumentElement() 允许直接显示根元素
- getElementsByTagName(String) 返回一个包含给定标记名的所有元素的节点列,其中节点以在树中出现的顺序为序
- getChildNodes() 返回此节点的所有子节点的 NodeList
- getParentNode() 给定节点的父节点
- getFirstChild() 返回给定节点的第一个子节点
- getLastChild() 返回给定节点的最后一个子节点
- getPreviousSibling() 给定节点的前一个同级节点
- getAttributes() 如果是一个元素,那么返回一个节点属性的NameNodeMap对象,否则返回空
- getNodeName() 返回代表节点标记名的字符串
- getNodeType() 代表对象类型
- getNodeValue() 节点值
- hasAttributes() 返回当前节点是否有属性
- hasChildNodes() 判断是否有子节点
写XML
-
- appendChild(Node newNode) 将节点 newChild 添加到此节点的子节点列表的末尾。
- cloneNode(boolean deep) 返回此节点的副本。副本节点没有父节点。如果deep参数为 true,则在指定节点下递归式克隆子树;如果为 false,则仅克隆节点本身。
- insertBefore(Node newNode,Node refNode) 在现有子节点 refChild 之前插入节点 - - newChild。如果refChild 为 null,则将 newChild 插入到子节点列表的末尾。如果 newChild 为 - DocumentFragment 对象,则以同样的顺序将其所有节点插入 refChild 之前。如果 newChild 已经存在于树中,则首先移除它。
- removeChild(Node oldNode) 从子节点列表中移除 oldChild 所指示的子节点,并将其返回。
- replaceChild(Node newNode,Node oldNode) 将子节点列表中的子节点 oldChild 替换为 - - newChild,并返回 oldChild 节点。
- setNodeValue(String nodeVAlue) 设置节点的值。此节点的值,取决于其类型。
- setPrefix(String prefix) 设置此节点的名称空间前缀;如果未指定,则为 null。当将它定义为 null 时,设置它无效,包括节点为只读的情况。
使用 Transformer 类写入输出结果
- 创建文档对象
- 创建 TransformerFactory的实例
- 使用 TransformerFactory 创建 Transformer的实例
- 使用 transform()方法将源树处理至输出结果中
特点
- 客户端应用程序可以定义一组 Java 接口用于创建、访问和操纵XML文档的内部结构
- 基于对象,与语言和平台无关
- 一次性将文档加载到内存中,在内存中解析和存储 XML 文档
- 将 XML 文档表示为树,整个XML文档被作为对象的体系结构排列
- 随机访问文档的不同部分对象,但只适合小型的文档
- 可读写
XML简单API(SAX):一种事件驱动的API
- 创建 SAXParserFactory 的实例
- 创建 SAXParser 的实例
- 创建 SAXParserHandler 类
- 使用 parse() 方法解析 XML 文档
“`
SAXParserFactory sf = SAXParserFactory.newInstance();
try {
InputStream is = getResources().getAssets().open(“fade_in.xml”);
SAXParser sp = sf.newSAXParser();
sp.parse(is, new DefaultHandler(){
@Override
public void startElement(String uri, String localName,
String qName, Attributes attributes)
throws SAXException {
Toast.makeText(MainActivity.this, qName+":"+attributes.getQName(0), 0).show();
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// String data = new String(ch,start,length);
// if(!TextUtils.isEmpty(data.trim()))
// Toast.makeText(MainActivity.this, “data: “+data, 0).show();
}
});
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}```
特点
- 适合解析大型文档
- 不能对文档进行随机访问
- 只读
- 只遍历文档一次