🚀前言
資料傳輸的資料格式有以下幾種常見的格式:
-
JSON(JavaScript Object Notation):JSON是一種輕量級的資料交換格式,可讀性高且易於解析。它使用鍵值對的方式表示資料,並且支援多層巢狀。
-
XML(eXtensible Markup Language):XML是一種標記語言,可用於儲存和傳輸結構化資料。它使用標籤來定義資料和資料之間的關係。
-
Form Data(表單資料):表單資料是一種常見的資料傳輸格式,透過HTTP請求中的表單提交進行資料傳輸,資料以鍵值對的形式存在。
完整的XML相關知識點可以看這篇文章:https://blog.csdn.net/aa2528877987/article/details/122660175
本文主要講解HarmonyOS中XML生成、解析、轉換。
🚀一、XML
🔎1.概述
XML是可擴充套件標記語言(eXtensible Markup Language)的縮寫。它是一種用於表示和傳輸結構化資料的標記語言。XML使用自定義的標籤來標記資料的各個部分,並使用起始標籤和結束標籤將資料包裹起來。這種結構化的格式使得資料可以被解析和處理,從而更好地進行資料交換和儲存。
與HTML類似,XML也使用尖括號(< >)來定義標籤。但與HTML不同,XML標籤是自定義的,可以根據需要建立新的標籤。XML還支援屬性,可以在標籤中新增額外的資訊。XML資料可以透過解析器解析為可用的物件,如樹狀結構或文件物件模型(DOM),從而進行進一步的處理和操作。
XML被廣泛應用於資料儲存、資料交換和Web服務等領域。它是一種通用的、可擴充套件的標記語言,可以適應不同的資料結構和應用需求。
🔎2.組成
XML文件是由元素、屬性和內容組成的。以下是它們的詳細解釋:
- 元素(element):XML文件的基本構建塊,也是文件的結構和資料的組織單元。元素由開始標籤和結束標籤組成,兩者之間包含了元素的內容。
例如:
<book>
<title>XML for Beginners</title>
<author>John Doe</author>
</book>
<book>、<title>和<author>都是元素。
- 屬性(attribute):元素的附加資訊,以名稱-值對的形式出現在開始標籤中。屬性提供有關元素的額外資訊。
例如:
<book category="fiction">
<title>XML for Beginners</title>
<author>John Doe</author>
</book>
category是book元素的屬性,其值為fiction。
- 內容(content):元素中的文字或其他元素。在元素的開始標籤和結束標籤之間可以包含文字或其他元素。
例如:
<book>
<title>XML for Beginners</title>
<author>John Doe</author>
</book>
<title>XML for Beginners</title>和<author>John Doe</author>是book元素的內容。
🔎3.文件結構定義形式
🦋3.1 XML Schema
在XML中使用XML Schema定義結構的方式是使用一個獨立的XML Schema檔案,該檔案定義了你希望XML文件符合的結構規範。
首先,建立一個XML Schema檔案,例如"example.xsd"。在該檔案中定義你的元素、屬性和資料型別。以下是一個示例XML Schema檔案的基本結構:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- 在這裡定義你的元素、屬性和資料型別 -->
</xs:schema>
接下來,在你的XML文件中引用該XML Schema檔案,以使XML文件與定義的結構匹配。為此,在XML文件的根元素上新增一個xmlns:xsi屬性和xsi:schemaLocation屬性。xmlns:xsi屬性指定XML名稱空間xsi的定義,xsi:schemaLocation屬性指定XML Schema檔案的位置。
下面是一個示例XML文件的基本結構,引用了上述的XML Schema檔案:
<?xml version="1.0" encoding="UTF-8"?>
<rootElement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.com example.xsd">
<!-- 在這裡編寫你的XML文件 -->
</rootElement>
xmlns:xsi屬性定義了xsi名稱空間,並指定了其定義的位置。xsi:schemaLocation屬性指定了XML Schema檔案的位置,其中"http://www.example.com"是XML名稱空間的URI,"example.xsd"是XML Schema檔案的位置。
該XML文件的結構和內容應符合在XML Schema檔案中定義的規範。如果XML文件與XML Schema不匹配,解析器將會報告錯誤。
🦋3.2 DTD
DTD(Document Type Definition)是一種用來定義XML文件結構的語言,它可以定義元素、屬性和實體的規則和約束。
<!DOCTYPE bookstore [
<!ELEMENT bookstore (book+)>
<!ELEMENT book (title, author, price)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT price (#PCDATA)>
<!ATTLIST book id ID #IMPLIED>
<!ATTLIST book category CDATA #REQUIRED>
]>
<bookstore>
<book category="Children">
<title>Harry Potter</title>
<author>J.K. Rowling</author>
<price>29.99</price>
</book>
<book category="Fiction">
<title>The Catcher in the Rye</title>
<author>J.D. Salinger</author>
<price>19.99</price>
</book>
</bookstore>
透過<!DOCTYPE>宣告引用了DTD定義,然後使用<!ELEMENT>定義了元素的結構,<!ATTLIST>定義了元素的屬性。
- 定義了bookstore元素必須包含一個或多個book元素。
- 定義了book元素包含title、author和price三個子元素。
- 定義了title元素只能包含文字內容。
- 定義了author元素只能包含文字內容。
- 定義了price元素只能包含文字內容。
- 定義了book元素有一個可選的id屬性,型別為ID。
- 定義了book元素必須有一個category屬性,型別為CDATA。
🔎4.生成
import xml from '@ohos.xml';
import util from '@ohos.util';
// 1.基於Arraybuffer構造XmlSerializer物件
// @ts-ignore
let arrayBuffer = new ArrayBuffer(2048); // 建立一個2048位元組的緩衝區
// @ts-ignore
let thatSer = new xml.XmlSerializer(arrayBuffer); // 基於Arraybuffer構造XmlSerializer物件
// 2.基於DataView構造XmlSerializer物件
// @ts-ignore
let arrayBuffer = new ArrayBuffer(2048); // 建立一個2048位元組的緩衝區
let dataView = new DataView(arrayBuffer); // 使用DataView物件操作ArrayBuffer物件
// @ts-ignore
let thatSer = new xml.XmlSerializer(dataView); // 基於DataView構造XmlSerializer物件
thatSer.setDeclaration(); // 寫入xml的宣告
thatSer.startElement('bookstore'); // 寫入元素開始標記
thatSer.startElement('book'); // 巢狀元素開始標記
thatSer.setAttributes('category', 'COOKING'); // 寫入屬性及屬性值
thatSer.startElement('title');
thatSer.setAttributes('lang', 'en');
thatSer.setText('Everyday'); // 寫入標籤值
thatSer.endElement(); // 寫入結束標記
thatSer.startElement('author');
thatSer.setText('Giada');
thatSer.endElement();
thatSer.startElement('year');
thatSer.setText('2005');
thatSer.endElement();
thatSer.endElement();
thatSer.endElement();
let view = new Uint8Array(arrayBuffer); // 使用Uint8Array讀取arrayBuffer的資料
let textDecoder = util.TextDecoder.create(); // 呼叫util模組的TextDecoder類
let res = textDecoder.decodeWithStream(view); // 對view解碼
console.info(res);
得到結果
<?xml version=\"1.0\" encoding=\"utf-8\"?>
<bookstore>\r\n
<book category=\"COOKING\">\r\n
<title lang=\"en\">Everyday</title>\r\n
<author>Giada</author>\r\n
<year>2005</year>\r\n
</book>\r\n
</bookstore>
🔎5.解析
🦋5.1 解析XML標籤和標籤值
import xml from '@ohos.xml';
import util from '@ohos.util'; // 需要使用util模組函式對檔案編碼
let strXml =
'<?xml version="1.0" encoding="utf-8"?>' +
'<note importance="high" logged="true">' +
'<title>Play</title>' +
'<lens>Work</lens>' +
'</note>';
let textEncoder = new util.TextEncoder();
let arrBuffer = textEncoder.encodeInto(strXml); // 對資料編碼,防止包含中文字元亂碼
// 1.基於ArrayBuffer構造XmlPullParser物件
let that = new xml.XmlPullParser(arrBuffer.buffer, 'UTF-8');
// // 2.基於DataView構造XmlPullParser物件
// let dataView = new DataView(arrBuffer.buffer);
// let that = new xml.XmlPullParser(dataView, 'UTF-8');
let str = '';
function func(name, value){
str = name + value;
console.info(str);
return true; //true:繼續解析 false:停止解析
}
let options = {supportDoctype:true, ignoreNameSpace:true, tagValueCallbackFunction:func};
that.parse(options);
得到結果
note
title
Play
title
lens
Work
lens
note
🦋5.2 解析XML屬性和屬性值
import xml from '@ohos.xml';
import util from '@ohos.util'; // 需要使用util模組函式對檔案編碼
let strXml =
'<?xml version="1.0" encoding="utf-8"?>' +
'<note importance="high" logged="true">' +
' <title>Play</title>' +
' <title>Happy</title>' +
' <lens>Work</lens>' +
'</note>';
let textEncoder = new util.TextEncoder();
let arrBuffer = textEncoder.encodeInto(strXml); // 對資料編碼,防止包含中文字元亂碼
let that = new xml.XmlPullParser(arrBuffer.buffer, 'UTF-8');
let str = '';
function func(name, value){
str += name + ' ' + value + ' ';
return true; // true:繼續解析 false:停止解析
}
let options = {supportDoctype:true, ignoreNameSpace:true, attributeValueCallbackFunction:func};
that.parse(options);
console.info(str); // 一次列印出所有的屬性及其值
🦋5.3 解析XML事件型別和元素深度
import xml from '@ohos.xml';
import util from '@ohos.util'; // 需要使用util模組函式對檔案編碼
let strXml =
'<?xml version="1.0" encoding="utf-8"?>' +
'<note importance="high" logged="true">' +
'<title>Play</title>' +
'</note>';
let textEncoder = new util.TextEncoder();
let arrBuffer = textEncoder.encodeInto(strXml); // 對資料編碼,防止包含中文字元亂碼
let that = new xml.XmlPullParser(arrBuffer.buffer, 'UTF-8');
let str = '';
function func(name, value){
str = name + ' ' + value.getDepth(); // getDepth 獲取元素的當前深度
console.info(str)
return true; //true:繼續解析 false:停止解析
}
let options = {supportDoctype:true, ignoreNameSpace:true, tokenValueCallbackFunction:func};
that.parse(options);
console.info(str); // 一次列印出所有的屬性及其值
得到結果
0 0 // 0:<?xml version="1.0" encoding="utf-8"?> 對應事件型別START_DOCUMENT值為0 0:起始深度為0
2 1 // 2:<note importance="high" logged="true"> 對應事件型別START_TAG值為2 1:深度為1
2 2 // 2:<title>對應事件型別START_TAG值為2 2:深度為2
4 2 // 4:Play對應事件型別TEXT值為4 2:深度為2
3 2 // 3:</title>對應事件型別END_TAG值為3 2:深度為2
3 1 // 3:</note>對應事件型別END_TAG值為3 1:深度為1(與<note對應>)
1 0 // 1:對應事件型別END_DOCUMENT值為1 0:深度為0
🦋5.4 場景示例
import xml from '@ohos.xml';
import util from '@ohos.util';
let strXml =
'<?xml version="1.0" encoding="UTF-8"?>' +
'<book category="COOKING">' +
'<title lang="en">Everyday</title>' +
'<author>Giada</author>' +
'</book>';
let textEncoder = new util.TextEncoder();
let arrBuffer = textEncoder.encodeInto(strXml);
let that = new xml.XmlPullParser(arrBuffer.buffer, 'UTF-8');
let str = '';
function tagFunc(name, value) {
str = name + value;
console.info('tag-' + str);
return true;
}
function attFunc(name, value) {
str = name + ' ' + value;
console.info('attri-' + str);
return true;
}
function tokenFunc(name, value) {
str = name + ' ' + value.getDepth();
console.info('token-' + str);
return true;
}
let options = {
supportDocType: true,
ignoreNameSpace: true,
tagValueCallbackFunction: tagFunc,
attributeValueCallbackFunction: attFunc,
tokenValueCallbackFunction: tokenFunc
};
that.parse(options);
得到結果
tag-
token-0 0
tag-book
attri-category COOKING
token-2 1
tag-title
attri-lang en
token-2 2
tag-Everyday
token-4 2
tag-title
token-3 2
tag-author
token-2 2
tag-Giada
token-4 2
tag-author
token-3 2
tag-book
token-3 1
tag-
token-1 0
🔎6.轉換
import convertxml from '@ohos.convertxml';
let xml =
'<?xml version="1.0" encoding="utf-8"?>' +
'<note importance="high" logged="true">' +
' <title>Happy</title>' +
' <todo>Work</todo>' +
' <todo>Play</todo>' +
'</note>';
let options = {
// trim: false 轉換後是否刪除文字前後的空格,否
// declarationKey: "_declaration" 轉換後檔案宣告使用_declaration來標識
// instructionKey: "_instruction" 轉換後指令使用_instruction標識
// attributesKey: "_attributes" 轉換後屬性使用_attributes標識
// textKey: "_text" 轉換後標籤值使用_text標識
// cdataKey: "_cdata" 轉換後未解析資料使用_cdata標識
// docTypeKey: "_doctype" 轉換後文件型別使用_doctype標識
// commentKey: "_comment" 轉換後註釋使用_comment標識
// parentKey: "_parent" 轉換後父類使用_parent標識
// typeKey: "_type" 轉換後元素型別使用_type標識
// nameKey: "_name" 轉換後標籤名稱使用_name標識
// elementsKey: "_elements" 轉換後元素使用_elements標識
trim: false, declarationKey: "_declaration",
instructionKey: "_instruction", attributesKey: "_attributes",
textKey: "_text", cdataKey: "_cdata", doctypeKey: "_doctype",
commentKey: "_comment", parentKey: "_parent", typeKey: "_type",
nameKey: "_name", elementsKey: "_elements"
}
let conv = new convertxml.ConvertXML();
let result = conv.convertToJSObject(xml, options);
let strRes = JSON.stringify(result); // 將js物件轉換為json字串,用於顯式輸出
console.info(strRes);
// 也可以直接處理轉換後的JS物件,獲取標籤值
let title = result['_elements'][0]['_elements'][0]['_elements'][0]['_text']; // 解析<title>標籤對應的值
let todo = result['_elements'][0]['_elements'][1]['_elements'][0]['_text']; // 解析<todo>標籤對應的值
let todo2 = result['_elements'][0]['_elements'][2]['_elements'][0]['_text']; // 解析<todo>標籤對應的值
console.info(title); // Happy
console.info(todo); // Work
console.info(todo2); // Play
🚀寫在最後
- 如果你覺得這篇內容對你還蠻有幫助,我想邀請你幫我三個小忙:
- 點贊,轉發,有你們的 『點贊和評論』,才是我創造的動力。
- 關注小編,同時可以期待後續文章ing🚀,不定期分享原創知識。
- 更多鴻蒙最新技術知識點,請關注作者部落格:https://t.doruo.cn/14DjR1rEY