使用Junit測試 需要純Java代碼,如果使用Android相關接口可能會出錯:
Method newInstance in org.xmlpull.v1.XmlPullParserFactory not mocked
註解:
jdk 1.5之後
@Deprecated 提醒用戶該方法是過時的(API中已經有更好的辦法來實現)
@SuppressWarnings("unused") 忽略警告("all")關閉所有警告
@Override 覆蓋父類方法
XML:
用具解決什麼問題?
1.通用大的數據交換格式
2。允許用戶自定義標籤,一個標籤用於描述一段數據
3.xml中的數據必須通過軟件來解釋
寫法:
1.文檔聲明
2.元素 \r\t都會被解析
3.屬性
4.註釋
5.CDATA區
<![CDATA[內容]]>
<?xml version="1.0" encoding="utf-8"?>
<!CDATA[[dddddddddddddddd]]>裏面的內容不會被解析
特殊符號:
& &
< <
> >
" "
' '
XML約束技術
常用的有DDT 和 Schema
DDT 文檔類型定義
XML解析 常用有dom sax pull
1.DOM解析
結構模型
xml文檔:
<html>
<head>
<title>HTML DOM</title>
<body>
<h1>DOM的結構</h1>
<p><a href="href">鏈接</a></h>
</body>
</head>
</html>
根據xml 層級結構會在內存中分配一個樹形結構
在xml dom每個元素都會被解析成一個Node
而常用的節點類型分爲:
元素節點 Element
屬性節點 Attr
文本節點 Text
文檔節點 Document
Dom解析優缺點:
因爲分配一個樹形結構,很方便實現增加修改刪除操作
如果文件過大,一次性在內存中分配一個樹形結構,造成內存溢出!
org.w3c.dom 提供DOM方式解析xml接口
org.xml.sax 提供SAX方式解析xml接口
DOM用法:
//dom 會把整個xml文檔加載到內存中
@Test
public void addData() throws TransformerException, IOException, SAXException, ParserConfigurationException {
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document parse = documentBuilder.parse("test1.xml");
NodeList nodeList = parse.getElementsByTagName("age");
//修改數據
nodeList.item(0).setTextContent("30");
//增加數據
Element e = parse.createElement("增加的元素");
e.setTextContent("11");
parse.getElementsByTagName("user").item(0).appendChild(e);
//在某個前面插入數據
Node user = parse.getElementsByTagName("user").item(2);
Node parentNode = user.getParentNode();
parentNode.insertBefore(e, user);
//刪除
Node age = parse.getElementsByTagName("age").item(1);
age.getParentNode().removeChild(age);
//增加屬性
Node age2 = parse.getElementsByTagName("age").item(0);
if (age2 instanceof Element) {
Element age21 = (Element) age2;
age21.setAttribute("ATC", "123");
}
//獲取屬性
Node age3 = parse.getElementsByTagName("age").item(0);
if (age3 instanceof Element) {
Element age213 = (Element) age3;
age213.getAttribute("ATC");
}
Source xmlsource = new DOMSource(parse);
Result outputTarget = new StreamResult("test1.xml");
transformer.transform(xmlsource, outputTarget);
for (int i = 0; i < nodeList.getLength(); i++) {
Node item = nodeList.item(i);
System.out.println("-");
}
}
xml最終運行結果:
SAX解析:邊讀邊解析,
優缺點:
不會造成內存溢出,但是不能修改xml文件
SaxReader(ContentHandler;ErrorHandler;DTDHandler;EntityHandler)
@Test
public void saxParser() throws ParserConfigurationException, SAXException, IOException {
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
SAXParser saxParser = saxParserFactory.newSAXParser();
XMLReader xmlReader = saxParser.getXMLReader();
MyContextHandler myContextHandler = new MyContextHandler();
xmlReader.setContentHandler(myContextHandler);
xmlReader.parse("test1.xml");
}
private class MyContextHandler extends DefaultHandler {
@Override
public void startDocument() throws SAXException {
super.startDocument();
System.out.println("文件開始");
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
System.out.println("開始標籤="+qName);
}
@Override
public void endDocument() throws SAXException {
super.endDocument();
System.out.println("文件結束");
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
super.endElement(uri, localName, qName);
System.out.println("結束標籤="+qName);
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
System.out.println("文本內容="+new String(ch,start,length));
}
}
PULL解析:
原理其實就是sax解析。
步驟》:
1.創建解析工廠
2.根據解析工廠創建解析器
3.把要操作的文件放到解析器裏面
例子:
//android 默認使用的是pull解析
@Test
public void pullParser() throws XmlPullParserException, IOException {
//獲取工廠
XmlPullParserFactory xmlPullParserFactory = XmlPullParserFactory.newInstance();
//獲取xml解析器
XmlPullParser xmlPullParser = xmlPullParserFactory.newPullParser();
xmlPullParser.setInput(new FileInputStream(new File("test1.xml")),
"utf-8");
int eventType = xmlPullParser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
//調用next方法解析下一個元素 來判斷是否繼續循環
eventType = xmlPullParser.next();
switch (eventType) {
case XmlPullParser.START_TAG:
//標籤
if ("name".equals(xmlPullParser.getName())) {
System.out.println(xmlPullParser.nextText());
}
break;
case XmlPullParser.END_TAG:
break;
default:
break;
}
}
}
生成xml:
//寫xml文件
ArrayList<SMS> arrayList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
for (int i = 0; i < 10; i++) {
SMS sms = new SMS();
sms.content = "內容" + i;
sms.from = "" + i;
sms.time = "1990-01-0" + i;
arrayList.add(sms);
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
stringBuilder.append("<SMSList>");
for (SMS sms : arrayList) {
stringBuilder.append("<SMS>");
stringBuilder.append("<from>");
stringBuilder.append(sms.from);
stringBuilder.append("</from>");
stringBuilder.append("<context>");
stringBuilder.append(sms.content);
stringBuilder.append("</context>");
stringBuilder.append("<time>");
stringBuilder.append(sms.time);
stringBuilder.append("</time>");
stringBuilder.append("</SMS");
}
stringBuilder.append("</SMSList>");
String xmlString = stringBuilder.toString();
try {
FileOutputStream fileOutputStream = openFileOutput("sms.xml", MODE_PRIVATE);
fileOutputStream.write(xmlString.getBytes());
fileOutputStream.close();
} catch (java.io.IOException e) {
e.printStackTrace();
}
xml序列化
//1.獲取序列化器
XmlSerializer xmlSerializer = Xml.newSerializer();
//2.給序列器設置一個輸出
try {
xmlSerializer.setOutput(openFileOutput("sms1.xml",MODE_PRIVATE),"utf-8");
//3.寫xml開頭
xmlSerializer.startDocument("utf-8", true);
//4.第一個參數 名稱空間,如果當前文件受某份schema約束就傳入名稱空間,否則null
xmlSerializer.startTag(null, "SMSList");
for (SMS sms : arrayList) {
xmlSerializer.startTag(null,"SMS");
xmlSerializer.startTag(null,"from");
xmlSerializer.text(sms.from);
xmlSerializer.endTag(null,"from");
xmlSerializer.startTag(null,"content");
xmlSerializer.text(sms.content);
xmlSerializer.endTag(null,"content");
xmlSerializer.startTag(null,"time");
xmlSerializer.text(sms.time);
xmlSerializer.endTag(null,"time");
xmlSerializer.endTag(null,"SMS");
}
xmlSerializer.endTag(null, "SMSList");
xmlSerializer.endDocument();
} catch (IOException e) {
e.printStackTrace();
}
}
android 下的xml pull解析
//android 自帶xml pull解析
XmlPullParser xmlPullParser = Xml.newPullParser();
try {
xmlPullParser.setInput(openFileInput("SMS1.xml"),"utf-8");
int eventType = xmlPullParser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_TAG:
if ("XXX".equals(xmlPullParser.getName())) {
} else if ("XXX".equals(xmlPullParser.getName())){
}
}
break;
default:
break;
}
eventType = xmlPullParser.next();
}}catch(Exception e){}
Json數據:
Json對比xml 更加省流量。(一個key對應一個value)
Json是JavaScript原生格式。
規則:
映射用冒號 : 名稱:值
並列的數據之間用逗號 , 名稱1:值1,名稱2:值2
映像的集合用(對象) {}
並列用的數據集合(數組 ) []
元素值類型有:string,number,object,array,true,false,null
Json解析框架:org.json,json-lib,gosn等