<vehicles xmlns="http://example.com/vehicles">
<item>
<name>Cars</name>
<description>I love cars.</description>
<models>
<model>Range Rover</model>
<model>Corolla</model>
<model>BMW</model>
<model>Toyota</model>
<model>Tesla</model>
</models>
</item>
</vehicles>

這些元素按層次結構進行組織,使文檔易于人類和計算機理解。

您可以使用如 JSONformatter(等工具來查看 XML 元素的樹狀結構。這一方法既適用于我們的示例,也適用于您所擁有的任何 XML 數據。以這種方式查看 XML 有助于您掌握元素的組織方式。

現在我們已經介紹了有關 XML 文件組件的基本信息,我們可以使用此信息來幫助解析具有各種庫的 XML 文件。

parse XML in JavaScript - Jsonformatter XML viewer

在 JavaScript 中解析 XML

XML 解析是分析 XML 文檔并提取所需數據的過程。

通常,XML 解析器執行以下關鍵步驟:

  1. 語法檢查:解析器檢查 XML 文檔是否符合 XML 語法規則。如果發現任何語法錯誤,例如缺少結束標簽或格式不正確的屬性值,解析器將報告這些錯誤,并且可能無法繼續處理文檔。
  2. 分詞:解析器將 XML 文檔分解為單獨的標記,例如開始標記、結束標記、屬性名稱和值以及文本內容。
  3. 構建文檔結構:解析器構建 XML 文檔的分層表示形式,通常采用樹結構。通過這個結構,我們可以遍歷整棵樹,查詢特定的元素或屬性,并根據實際需求對數據進行相應的操作。

JavaScript XML 解析器

創建自定義 XML 解析通常具有挑戰性,尤其是在實現自定義解決方案時。

XML 文件執行更嚴格的規則;例如,缺少沒有引號的標簽或屬性可能會導致文件不可用。另外,由于XML文檔具有自描述性質,因此很難將其拆分成能夠并行解析的塊。

除非您有充分的理由,否則,使用標準且經過充分測試的解析器庫和API,以避免解析過程的復雜性,會是一個更為有效的選擇。

與其他語言一樣,JavaScript 提供了多個可用于解析 XML 文件的 API 和庫。他們每個人都有其獨特的權衡。

有些針對速度進行了優化,有些針對內存進行了優化;無論您選擇使用哪種方式,在很大程度上取決于您的項目要求。

在本指南中,我們將介紹以下內容:

  1. DOMParser API
  2. xml2js
  3. 使用 Streams
  4. SAX 解析器

方法 1:使用DOMParser API

文檔對象模型 (DOM) 將文檔的結構表示為節點樹,其中每個節點對應于標記中的元素、屬性或值。

此樹結構允許解析器以編程方式訪問、操作和修改 XML 內容。

JavaScript 提供了DOMParser API,它提供了一種方法,可以將XML內容解析成XML文檔,這些文檔能夠輕松地遍歷和訪問,以便進行后續的處理。

現在,讓我們看看如何使用此 API 解析 XML。首先,創建一個本地開發環境,我們將使用它來處理代碼示例,同時按照本指南進行操作。

為此,請在終端中運行以下命令以創建一個演示項目目錄和兩個文件:.index.和一個 jstest.xml

mkdir parsing-xml
cd parsing-xml

# For Linux/Unix systems:
touch index.js test.xml

# For Windows:
_echo. > index.js_
echo. > test.xml

然后,在 XML 示例中的test.xml 粘貼中,我們查看了如下:

<?xml version="1.0" encoding="UTF-8"?>
<vehicles xmlns="http://example.com/vehicles">
<item>
<name>Cars</name>
<description>I love cars.</description>
<models>
<model>Range Rover</model>
<model>Corolla</model>
<model>BMW</model>
<model>Toyota</model>
<model>Tesla</model>
</models>
</item>
</vehicles>

要使用 DOMParser API 解析 XML 數據,需要注意幾個要點。

DOMParser API 是現代瀏覽器中支持的本機 Web API。即便如此,在處理 XML 文件時,也不能使用 DOMParser API 實例方法直接解析它們,即 parseFromString()— 該方法需要 XML 字符串作為輸入,而不是文件路徑或 URL。

換句話說,它不具備從文件系統中讀取文件或向服務器發送請求以獲取XML文件的功能。相反,它的設計初衷是處理那些在內存中已經可用的XML源代碼字符串。

由于預期是您將處理需要在任何其他處理之前進行解析的大型 XML 文件,因此正確加載這些文件非常重要。為此,您需要:

  1. 使用 fetch API 或其他方法獲取 XML 文件。
  2. 將獲取的 XML 文件轉換為字符串。
  3. 最后,將parseFromString()字符串傳遞給 DOMParser API 實例方法進行解析。

完成這些步驟后,您可以使用 DOM 方法訪問解析的 XML。

讓我們看一個代碼可能是什么樣子的示例。在index.js文件中,粘貼以下代碼:

async function loadXML() {
try {
const response = await fetch('test.xml');
const xmlString = await response.text();
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlString, 'text/xml');

const name = xmlDoc.querySelector('name').textContent;
console.log(name);
} catch (error) {
console.error('Error loading XML:', error);
}
}

loadXML()

現在,在同一個項目目錄中,創建一個文件并添加以下代碼:

<!DOCTYPE html>
<html>
<head>
<title>XML Parser</title>
</head>
<body>
<script src="index.js"></script>
</body>
</html>

此時,要顯示解析后的名稱,請在瀏覽器中打開index.html文件,導航到開發人員工具中的瀏覽器控制臺,并希望能查看輸出。

這種方法在技術上是正確的。但是,由于我們使用 Fetch API 在您的本地環境中加載 XML 文件,因此它不會工作,并且瀏覽器很可能會引發錯誤。這是因為 Web 服務器尚未提供文件。

現代瀏覽器使用同源安全策略。這個策略會阻止網頁向不同于為該頁面提供服務的域的其它域發起請求。在使用 Fetch API 本地加載 XML 文件時,我們就會遇到這樣的策略限制。這是一項安全措施,但它可能會阻礙當地發展。

當您直接從文件系統打開 HTML 文件時,瀏覽器會將其視為具有唯一的來源。使用 JavaScript 的 Fetch API 獲取本地文件(包括 XML 文件)的任何嘗試都將被同源策略阻止。瀏覽器可能會因為跨域請求(CORS)策略而引發阻止錯誤,或者出現其他與安全相關的類似錯誤。

為了克服這個限制,我們需要從 Web 服務器提供我們的文件。這種方法確保我們的所有文件(HTML、JavaScript 和 XML)都從同一源提供,從而滿足同源策略要求。

有幾種方法可以實現此目的:

  1. 使用本地開發服務器:可以使用 Node.js 和 Express 等工具來設置簡單的本地服務器。
  2. 或者,在終端中運行以提供文件。
  3. 代碼編輯器擴展(如 Live Server 擴展)可以使用最少的配置啟動本地服務器。這將在您的代碼編輯器中模擬相同的服務器端環境,作為提供文件的替代方案。

在本演示中,我們將在 Visual Studio Code 中使用 Live Server 擴展。這個擴展提供了一個快速且簡便的方法,使我們能夠在本地提供文件,而無需進行復雜的服務器設置。

要使用 Live Server:

  1. 打開 Visual Studio Code 并導航到 Extensions 選項卡。
  2. 在擴展市場中搜索 Live Server
  3. 單擊 Live Server 擴展的 Install 按鈕。
  4. 安裝后,您將在 VS Code 窗口底部的狀態欄中看到一個 Go Live (上線) 按鈕。
  5. 單擊 Go Live 按鈕啟動本地服務器并在默認 Web 瀏覽器中自動打開 index.html 文件。
parse XML in JavaScript - Live server

在本地服務器運行后,您的瀏覽器現在可以獲取 XML 文件。

要打開瀏覽器的控制臺,您需要訪問瀏覽器的開發人員工具。為此,請右鍵單擊,選擇 檢查,然后單擊 控制臺 選項卡。

在這里,您應該看到 XML 解析腳本的輸出。

parse XML in JavaScript - output xml parsing script

這種設置允許我們在瀏覽器中使用 DOMParser API 直接解析 XML 文件。此基本步驟為更復雜的 XML 處理任務奠定了基礎。

上面的示例主要聚焦于在瀏覽器環境中解析XML內容。但值得注意的是,相同的過程在服務器端環境中同樣適用——您依然可以使用相同的DOMParser API方法來解析XML數據。

這可以使用像 XMLDOM 這樣的包來實現 — 它提供了一個 DOMParser 實現,允許您在 Node.js 服務器環境中解析 XML。

要使用 ,我們首先需要設置一個本地服務器端開發環境。為此,您需要首先安裝 Node.js 和 Node 包管理器 npm。

首先,為此示例創建一個新的項目目錄,或者您可以使用當前的工作目錄。然后,通過在終端中運行以下命令來初始化新的 Node.js 項目:

npm init --y

接下來,安裝 .xmldom

npm install @xmldom/xmldom

現在,在項目文件夾的根目錄中,創建一個新文件。

# For Linux/Unix systems:
touch app.js

# For Windows:
_echo. > app.js_

然后,粘貼以下代碼:

import fs from 'fs';
import { DOMParser } from '@xmldom/xmldom';

const xml = fs.readFileSync('test.xml', 'utf8');
const parser = new DOMParser();
const doc = parser.parseFromString(xml, 'application/xml');

console.log(doc.getElementsByTagName('name')[0].textContent);

在此示例中,我們執行兩個主要操作:

  1. 使用 Node.js fs模塊將整個 XML 文件 (test.xml) 作為字符串同步讀入內存。
  2. 創建 DOMParser的實例并使用parseFromString方法解析 XML 數據。

解析后,我們可以使用 DOM 遍歷方法訪問單個元素。在這種情況下,我們使用 getElementsByTagNametextContent檢索第一個元素的文本內容。

確保通過添加屬性來更新文件,以便在文件中使用 ES6 語法。

您可以在終端上運行此命令來測試此最小設置。

node app.js

輸出將是 XML 文件中第一個元素的文本內容,即:.Cars

方法 2:使用 XML2JS

xml2js 庫是用于解析 XML 數據的常用 Node.js 包。與DOMParser(它提供XML的DOM表示)不同,這個方法更側重于將XML轉換為一種更便于在JavaScript應用程序中使用的格式。

對于您希望快速訪問API或其他服務中的數據,而又不想處理通過操作DOM來訪問所需數據的復雜性的場景,它特別有用。

實質上,xml2js允許您將 XML 直接解析為 JSON 格式。由于 JSON 是應用程序中使用的一種常見格式,因此您的使用者(API、客戶端等)可以輕松攝取和使用解析后的數據。

要使用 ,首先,安裝軟件包:xml2js

npm install xml2js

安裝后,要解析 XML 文件,請首先使用fs模塊讀取文件,然后使用xml2js將 XML 字符串轉換為 JavaScript 對象。

下面是如何執行此操作的示例:

import fs from 'fs';
import { parseString } from 'xml2js';

const xml = fs.readFileSync('test.xml', 'utf8');

parseString(xml, (err, result) => {
if (err) {
console.error('Error parsing XML:', err);
return;
}
console.log(result);
});

在此代碼片段中,我們讀取 test.xml字符串的內容,然后使用該parseString函數將 XML 字符串轉換為 JavaScript 對象(JSON 對象)。

當您運行此代碼時,您將獲得如下輸出:

{
vehicles: { '$': { xmlns: '[http://example.com/vehicles](http://example.com/vehicles)' }, item: [ [Object] ] }
}

這并不完全是錯誤,您不用擔心!這種輸出的原因是parseString方法遵循了Node.js的默認行為,即在記錄大型或嵌套的對象時,通常會限制檢查的深度,因此導致了這樣的輸出(這一行為在GitHub存儲庫中有明確的說明)。

要查看已解析的 XML 的完整結構,可以使用util.inspect方法。現在,您可以獲得 JSON 對象的更詳細結構。

繼續導入util模塊,將result對象包裝在util.inspect方法中,然后將其記錄在終端中。

import util from 'util';
console.log(util.inspect(result, { depth: null, colors: true }));

這將為您提供已解析的 XML 對象的詳細視圖,包括所有嵌套屬性。

假設您希望從此解析的對象中訪問各個項目。為此,您可以遍歷每個嵌套項并記錄每個嵌套項,如下所示:

    const items = result.vehicles.item;
items.forEach(item => {
console.log('Name:', item.name[0]);
console.log('Description:', item.description[0]);
console.log('Models:', item.models[0].model[0]);
});

XMLDOM 與 XML2JS:有什么區別?

現在,我們已經了解了兩個很棒的解析庫,xmldomxml2js,盡管如此,在解析過程中使用這兩者時,有一些重要的權衡值得考慮。

對于初學者來說,xmldom提供了XML的DOM表示作為輸出。要訪問和操作這些數據,您需要利用標準的DOM方法來遍歷DOM樹。

相反,xml2js將 XML 直接轉換為 JavaScript 對象。這簡化了數據訪問和操作。這種方法更直觀,允許與數據直接交互,而無需導航 DOM 樹。

性能在所有軟件進程中都很重要,包括 XML 解析。對于大型 XML 文檔,將其解析為 DOM 可能會消耗大量資源。特別是當 XML 深度嵌套時,管理完整的 DOM 結構可能會顯著降低處理速度。

相比之下,xml2js在解析和訪問數據時通常更加迅速,原因在于它直接將XML轉換為JavaScript對象,避免了產生DOM表示所帶來的額外開銷。這可以在主要讀取 XML 數據的應用程序中獲得更好的性能。

方法 3:使用 Stream 模塊解析大型 XML 文件

在處理大型 XML 文件時,將整個文檔加載到內存中可能效率低下,并導致性能瓶頸。要有效地處理大型 XML 文件,您可以使用Stream模塊以塊的形式處理 XML 數據,而不是一次加載所有數據。

該模塊是一個內置的 Node.js 模塊,它提供了一種處理流數據的方法。它使得您可以按較小的數據塊進行讀取或寫入操作,這在處理大型文件或數據流時顯得尤為有用。

要測試 Stream 模塊,請繼續創建一個新文件并包含large.xml內容。理想情況下,它不是一個大型 XML 文件,但對于此演示,我們將使用它:

<?xml version="1.0" encoding="UTF-8"?>
<vehicles xmlns="http://example.com/vehicles">
<vehicle type="http://example.com/car">
<name>Cars</name>
<description>I love cars.</description>
<models>
<model>Range Rover</model>
<model>Corolla</model>
<model>BMW</model>
<model>Toyota</model>
<model>Tesla</model>
</models>
</vehicle>
<vehicle type="http://example.com/motorcycle">
<name>Motorcycles</name>
<description>I also enjoy riding motorcycles.</description>
<models>
<model>Harley-Davidson</model>
<model>Honda</model>
<model>Yamaha</model>
<model>Ducati</model>
<model>Triumph</model>
</models>
</vehicle>
<vehicle type="http://example.com/minivan">
<name>Minivans</name>
<description>Minivans .</description>
<models>
<model>Honda Odyssey</model>
<model>Toyota Sienna</model>
<model>Chrysler Pacifica</model>
<model>Kia Carnival</model>
<model>Dodge Grand Caravan</model>
</models>
</vehicle>
</vehicles>

接下來,創建一個在同一目錄中調用的新文件test-stream.js。將以下代碼復制并粘貼到該文件中。

此外,由于xml2js在處理大型 XML 數據方面做得很好,我們可以輕松地將兩者結合起來,如下所示:

import fs from 'fs';
import { Parser } from 'xml2js';
import util from 'util';

const parser = new Parser();

const readStream = fs.createReadStream('large.xml', 'utf8');

readStream.on('data', (chunk) => {
parser.parseString(chunk, (err, result) => {
if (err) {
console.error('Error parsing XML:', err);
return;
}
console.log('Parsed data:', util.inspect(result, { depth: null, colors: true }));
});
});

readStream.on('end', () => {
console.log('process completed');
});

readStream.on('error', (err) => {
console.error('Error:', err);
});

在此示例中,我們從庫中導入fs模塊和parseString函數。我們創建一個新實例,該parseString.Parser實例將用于解析 XML 數據。

接下來,我們使用 fs.createReadStream 來創建一個讀取流,并傳遞文件路徑(例如 'large.xml')和編碼(例如 'utf8')。這個讀取流將會以塊的形式來讀取文件。

在讀取流(readStream)上監聽'data'事件以接收新的數據塊,并使用某個解析器(可能是xml2js或類似的庫中的parseString方法)來解析這些數據塊。

使用 command 啟動節點服務器,在node test-stream.js終端中查看結果。

此實現能夠無需一次性將整個大型 XML 文件加載到內存中,而是通過讀取、處理和解析較小的數據塊來有效地處理該示例文件。

對于生產應用程序,XML 文件可能比我們的示例大得多。這些數據塊通常需要在被使用前進行適當的處理。如果不加以注意,它們可能會給您的應用程序帶來沉重的負擔,從而導致整體性能下降。有效地處理大型 XML 文件對于保持系統平穩運行非常重要。

使用流讀取和解析數據有助于避免這些問題。您還可以使用 Sax.js 等包,它將 XML 作為流進行處理。這些方法可讓您更高效地處理大型 XML 文件,從而保持應用程序的響應速度。

寫入 XML 文件

讓我們換個方向,探討一下如何從零開始創建一個XML文件,這涉及將數據寫入XML文件中。整個流程首先是構建出XML的結構,接著再將其序列化為具體的文件。

您可以使用一些庫來實現此目的,包括 xml2jsxmldom用于更復雜的 XML 生成。

讓我們看一個使用 xml2jsBuilder,此庫提供了一個類,可以輕松地將 JavaScript 對象轉換為 XML。

在此示例中,創建一個名為 write-xml.js的新文件。我們將使用此文件來寫入 XML 數據。

首先,從 fs中導入Builder模塊和xml2js類。

import fs from 'fs';
import { Builder } from 'xml2js';

接下來,創建一個 JavaScript 對象,該對象表示要創建的 XML 結構。此對象應具有與我們要生成的 XML 文件相同的結構。

const obj = {
vehicles: {
item: [
{
$: { name: 'Car' },
carDetails: 'Details about the car'
},
{
$: { name: 'Bike' },
bikeDetails: 'Details about the bike'
}
]
}
};

現在,使用實例將 JavaScript 對象轉換為 XML 字符串,如下所示:Builder

const builder = new Builder();
const xml = builder.buildObject(obj);

最后,使用 :fs.writeFileSync

fs.writeFileSync('output.xml', xml, 'utf8');
console.log('XML file written.');

沒錯!這就是利用xml2js庫從頭開始創建XML文件的方式。雖然這只是一個簡單的例子,但它著重展示了將數據寫入XML文件的基本流程。

在 JavaScript 中解析 XML 的常見問題和解決方案

有許多工具可用于解析 XML。無論您使用的是小文件還是大文件,都要記住以下幾個關鍵點,以及 XML 解析的一些常見問題以及如何修復它們:

  1. 選擇合適的庫:第一步是為您的項目選擇合適的 XML 解析工具。不同的庫可以說有優點和缺點,其中一些是重疊的。請務必考慮重要的權衡和目標解析要求。
  2. 處理命名空間:XML命名空間通過為元素提供唯一標識來增加XML的復雜性。在解析帶有命名空間的XML時,應選擇那些支持命名空間的庫,并根據XML的架構來驗證其結構。這些步驟可以防止錯誤并確保正確的數據處理。在線工具可以幫助進行架構驗證,從而提高應用程序的 XML 處理能力。
  3. 解析不明確或不完整的 XML:這通常是由于缺少元素或屬性,或者 XML 結構不正確而發生的。將錯誤處理工具(如 try-catch 塊或錯誤回調)添加到您的代碼中以處理這些問題。這些工具可以捕獲和管理意外的 XML 數據,這有助于防止您的應用崩潰。
  4. 大文件的性能問題:當文件太大而無法放入內存,或者解析過程花費的時間太長時,可能會發生這種情況。為了解決這個問題,可以采用流式處理方法。這種方法能夠讓您以數據塊的形式來解析XML數據,而不是一次性地將整個文件加載到內存中。

結論

XML 解析有許多實際用途。您可能會使用 JavaScript 和 Node.js 來進行網頁抓取,或者處理更復雜的應用程序中的 XML 數據。您在這里掌握的技能,將會成為您在未來JavaScript項目中處理結構化數據時堅實的基石。

原文鏈接:https://blog.apify.com/javascript-parse-xml/

上一篇:

React vs Vue:2024年技術對比與應用場景分析

下一篇:

React vs Vue:2024年技術對比與應用場景
#你可能也喜歡這些API文章!

我們有何不同?

API服務商零注冊

多API并行試用

數據驅動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內容創意新穎性、情感共鳴力、商業轉化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費