鴻蒙HarmonyOS實戰-ArkTS語言基礎類庫(XML)
??前言
數據傳輸的數據格式有以下幾種常見的格式:
-
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


浙公網安備 33010602011771號